http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java deleted file mode 100644 index 39663dd..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpAction.java +++ /dev/null @@ -1,290 +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.servlets; - -import static com.hp.hpl.jena.query.ReadWrite.READ ; -import static com.hp.hpl.jena.query.ReadWrite.WRITE ; - -import java.util.HashMap ; -import java.util.Map ; - -import javax.servlet.http.HttpServletRequest ; -import javax.servlet.http.HttpServletResponse ; - -import org.apache.jena.atlas.logging.Log ; -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.DatasetRef ; -import org.apache.jena.fuseki.server.ServiceRef ; - -import com.hp.hpl.jena.query.ReadWrite ; -import com.hp.hpl.jena.sparql.SystemARQ ; -import com.hp.hpl.jena.sparql.core.DatasetGraph ; -import com.hp.hpl.jena.sparql.core.DatasetGraphWithLock ; -import com.hp.hpl.jena.sparql.core.DatasetGraphWrapper ; -import com.hp.hpl.jena.sparql.core.Transactional ; - -/** - * HTTP action that represents the user request lifecycle. Its state is handled in the - * {@link SPARQL_ServletBase#executeLifecycle(HttpAction)} method. - */ -public class HttpAction -{ - public final long id ; - public final boolean verbose ; - - // Phase two items - set and valida after the datasetRef is known. - private DatasetGraph dsg ; // The data - public DatasetRef dsRef ; - public ServiceRef srvRef ; - - private Transactional transactional ; - private boolean isTransactional; - private DatasetGraph activeDSG ; // Set when inside begin/end. - private ReadWrite activeMode ; // Set when inside begin/end. - - private boolean startTimeIsSet = false ; - private boolean finishTimeIsSet = false ; - - private long startTime = -2 ; - private long finishTime = -2 ; - - // Incoming - //public final - - // Outcome. - int statusCode = -1 ; - String message = null ; - int contentLength = -1 ; - String contentType = null ; - - // Cleared to archive: - Map <String, String> headers = new HashMap<String, String>() ; - public HttpServletRequest request; - public HttpServletResponseTracker response ; - - /** - * Creates a new HTTP Action, using the HTTP request and response, and a given ID. - * - * @param id given ID - * @param request HTTP request - * @param response HTTP response - * @param verbose verbose flag - */ - public HttpAction(long id, HttpServletRequest request, HttpServletResponse response, boolean verbose) { - this.id = id ; - this.request = request ; - this.response = new HttpServletResponseTracker(this, response) ; - // Should this be set when setDataset is called from the dataset context? - // Currently server-wide, e.g. from the command line. - this.verbose = verbose ; - } - - /** - * <p>Sets the action dataset. Setting a {@link DatasetRef} will replace any existing DatasetRef, as well as - * as the {@link DatasetGraph} of the current HTTP Action.</p> - * - * <p>Once it has updated its members, the HTTP Action will change its transactional state and - * {@link Transactional} instance according to its base dataset graph.</p> - * - * @param desc {@link DatasetRef} - * @see Transactional - * @see DatasetGraphWrapper - */ - public void setDataset(DatasetRef desc) { - this.dsRef = desc ; - this.dsg = desc.dataset ; - DatasetGraph basedsg = unwrap(dsg) ; - - if ( isTransactional(basedsg) && isTransactional(dsg) ) { - // Use transactional if it looks safe - abort is necessary. - transactional = (Transactional)dsg ; - isTransactional = true ; - } else { - // Unsure if safe - transactional = new DatasetGraphWithLock(dsg) ; - // No real abort. - isTransactional = false ; - } - } - - /** - * Returns <code>true</code> iff the given {@link DatasetGraph} is an instance of {@link Transactional}, - * <code>false otherwise</code>. - * - * @param dsg a {@link DatasetGraph} - * @return <code>true</code> iff the given {@link DatasetGraph} is an instance of {@link Transactional}, - * <code>false otherwise</code> - */ - private static boolean isTransactional(DatasetGraph dsg) { - return (dsg instanceof Transactional) ; - } - - /** - * A {@link DatasetGraph} may contain other <strong>wrapped DatasetGraph's</strong>. This method will return - * the first instance (including the argument to this method) that <strong>is not</strong> an instance of - * {@link DatasetGraphWrapper}. - * - * @param dsg a {@link DatasetGraph} - * @return the first found {@link DatasetGraph} that is not an instance of {@link DatasetGraphWrapper} - */ - private static DatasetGraph unwrap(DatasetGraph dsg) { - while (dsg instanceof DatasetGraphWrapper) { - dsg = ((DatasetGraphWrapper)dsg).getWrapped() ; - } - return dsg ; - } - - /** - * Sets the {@link ServiceRef}. - * - * @param srvRef a {@link ServiceRef} - */ - public void setService(ServiceRef srvRef) { - this.srvRef = srvRef ; - } - - /** - * Returns whether or not the underlying DatasetGraph is fully transactional (supports rollback). - * @return <code>true</code> if the underlying DatasetGraph is fully transactional (supports rollback), - * <code>false</code> otherwise. - */ - public boolean isTransactional() { - return isTransactional ; - } - - public void beginRead() { - activeMode = READ ; - transactional.begin(READ) ; - activeDSG = dsg ; - dsRef.startTxn(READ) ; - } - - public void endRead() { - dsRef.finishTxn(READ) ; - activeMode = null ; - transactional.end() ; - activeDSG = null ; - } - - public void beginWrite() { - transactional.begin(WRITE) ; - activeMode = WRITE ; - activeDSG = dsg ; - dsRef.startTxn(WRITE) ; - } - - public void commit() { - transactional.commit() ; - activeDSG = null ; - } - - public void abort() { - try { transactional.abort() ; } - catch (Exception ex) { - // Some datasets claim to be transactional but - // don't provide a real abort. We tried to avoid - // them earlier but even if they sneek through, - // we try to continue server operation. - Log.warn(this, "Exception during abort (operation attempts to continue): "+ex.getMessage()) ; - } - activeDSG = null ; - } - - public void endWrite() { - dsRef.finishTxn(WRITE) ; - activeMode = null ; - - if ( transactional.isInTransaction() ) { - Log.warn(this, "Transaction still active in endWriter - no commit or abort seen (forced abort)") ; - try { - transactional.abort() ; - } catch (RuntimeException ex) { - Log.warn(this, "Exception in forced abort (trying to continue)", ex) ; - } - } - transactional.end() ; - activeDSG = null ; - } - - public final DatasetGraph getActiveDSG() { - return activeDSG ; - } - - public final DatasetRef getDatasetRef() { - return dsRef ; - } - - /** Reduce to a size that can be kept around for sometime */ - public void minimize() { - this.request = null ; - this.response = null ; - } - - public void setStartTime() { - if ( startTimeIsSet ) - Log.warn(this, "Start time reset") ; - startTimeIsSet = true ; - this.startTime = System.nanoTime() ; - } - - public void setFinishTime() { - if ( finishTimeIsSet ) - Log.warn(this, "Finish time reset") ; - finishTimeIsSet = true ; - this.finishTime = System.nanoTime() ; - } - - public HttpServletRequest getRequest() { return request ; } - - public HttpServletResponseTracker getResponse() { return response ; } - - /** Return the recorded time taken in milliseconds. - * {@linkplain #setStartTime} and {@linkplain #setFinishTime} - * must have been called. - */ - public long getTime() - { - if ( ! startTimeIsSet ) - Log.warn(this, "Start time not set") ; - if ( ! finishTimeIsSet ) - Log.warn(this, "Finish time not set") ; - return (finishTime-startTime)/(1000*1000) ; - } - - public void sync() { - SystemARQ.sync(dsg) ; - } - - public static MediaType contentNegotationRDF(HttpAction action) { - MediaType mt = ConNeg.chooseContentType(action.request, DEF.rdfOffer, DEF.acceptRDFXML) ; - if ( mt == null ) - return null ; - if ( mt.getContentType() != null ) - action.response.setContentType(mt.getContentType()) ; - if ( mt.getCharset() != null ) - action.response.setCharacterEncoding(mt.getCharset()) ; - return mt ; - } - - public static MediaType contentNegotationQuads(HttpAction action) { - return ConNeg.chooseContentType(action.request, DEF.quadsOffer, DEF.acceptNQuads) ; - } -}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java deleted file mode 100644 index c39e728..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/HttpServletResponseTracker.java +++ /dev/null @@ -1,140 +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.servlets; - -import java.io.IOException ; - -import javax.servlet.http.HttpServletResponse ; -import javax.servlet.http.HttpServletResponseWrapper ; - -import org.apache.jena.atlas.logging.Log ; - -/** Intercepting wrapper so we can track the response settings for logging purposes */ - -public class HttpServletResponseTracker extends HttpServletResponseWrapper -{ - private final HttpAction action ; - - public HttpServletResponseTracker(HttpAction action, HttpServletResponse response) - { - super(response) ; - this.action = action ; - } - - @Override - public void sendError(int sc, String msg) throws IOException - { - action.statusCode = sc ; - action.message = msg ; - super.sendError(sc, msg) ; - } - - @Override - public void sendError(int sc) throws IOException - { - action.statusCode = sc ; - action.message = null ; - super.sendError(sc) ; - } - - @Override - public void setHeader(String name, String value) - { - super.setHeader(name, value) ; - action.headers.put(name, value) ; - } - - @Override - public void addHeader(String name, String value) - { - Log.warn(this, "Unexpected addHeader - not recorded in log") ; - super.addHeader(name, value) ; - } - @Override - public void setStatus(int sc) - { - action.statusCode = sc ; - action.message = null ; - super.setStatus(sc) ; - } - - @Override - @Deprecated - public void setStatus(int sc, String sm) - { - action.statusCode = sc ; - action.message = sm ; - super.setStatus(sc, sm) ; - } - - @Override - public void setContentLength(int len) - { - action.contentLength = len ; - super.setContentLength(len) ; - } - - @Override - public void setContentType(String type) - { - action.contentType = type ; - super.setContentType(type) ; - } - - // From HttpServletResponse -// public void addCookie(Cookie cookie) {} -// public boolean containsHeader(String name) {} -// public String encodeURL(String url) { } -// public String encodeRedirectURL(String url) {} -// public String encodeUrl(String url) {} -// public String encodeRedirectUrl(String url) {} -// public void sendError(int sc, String msg) throws IOException -// public void sendError(int sc) throws IOException -// public void sendRedirect(String location) throws IOException {} -// public void setDateHeader(String name, long date) {} -// public void addDateHeader(String name, long date) {} -// public void setHeader(String name, String value) -// public void addHeader(String name, String value) -// public void setIntHeader(String name, int value) {} -// public void addIntHeader(String name, int value) {} -// public void setStatus(int sc) -// public void setStatus(int sc, String sm) -// public void sendRedirect(String location) throws IOException {} -// public void setDateHeader(String name, long date) {} -// public void addDateHeader(String name, long date) {} - - // From ServletResponse. -// public ServletResponse getResponse() {} -// public void setResponse(ServletResponse response) {} -// public void setCharacterEncoding(String charset) {} -// public String getCharacterEncoding() {} -// public ServletOutputStream getOutputStream() throws IOException {} -// public PrintWriter getWriter() throws IOException {} -// public void setContentLength(int len) {} -// public void setContentType(String type) {} -// public String getContentType() { -// public void setBufferSize(int size) {} -// public int getBufferSize() {} -// public void flushBuffer() throws IOException {} -// public boolean isCommitted() {} -// public void reset() {} -// public void resetBuffer() {} -// public void setLocale(Locale loc) {} -// public Locale getLocale() {} -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java deleted file mode 100644 index 63e6562..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/NullOutputStream.java +++ /dev/null @@ -1,53 +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.servlets; - -import java.io.* ; - -/** -* Code needed to implement an OutputStream that does nothing. -*/ - - -public class NullOutputStream extends /*Filter*/OutputStream -{ - public NullOutputStream() - { - } - - // The OutputStream operations - @Override - public void close() { /* .close() ;*/ } - @Override - public void flush() { /* .flush() ;*/ } - - // Need to implement this one. - @Override - public void write(int b) { /* .write(b) ;*/ } - @Override - public void write(byte b[]) { /* this.write(b, 0, b.length) ; */} - - // Good to implement this one. - @Override - public void write(byte[] b, int off, int len) - { - // Work function - } - -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads.java deleted file mode 100644 index 06c38b7..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/REST_Quads.java +++ /dev/null @@ -1,211 +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.servlets; - -import static java.lang.String.format ; - -import java.io.IOException ; - -import javax.servlet.ServletOutputStream ; - -import org.apache.jena.atlas.web.MediaType ; -import org.apache.jena.atlas.web.TypedOutputStream ; -import org.apache.jena.fuseki.Fuseki ; -import org.apache.jena.fuseki.HttpNames ; -import org.apache.jena.riot.Lang ; -import org.apache.jena.riot.RDFDataMgr ; -import org.apache.jena.riot.RDFLanguages ; -import org.apache.jena.riot.ReaderRIOT ; -import org.apache.jena.riot.system.StreamRDF ; -import org.apache.jena.riot.system.StreamRDFLib ; - -import com.hp.hpl.jena.graph.Graph ; -import com.hp.hpl.jena.graph.Node ; -import com.hp.hpl.jena.graph.NodeFactory ; -import com.hp.hpl.jena.sparql.core.DatasetGraph ; - -/** - * Servlet that serves up quads for a dataset. - */ - -public class REST_Quads extends SPARQL_REST -{ - public REST_Quads() { super(); } - - @Override - protected void validate(HttpAction action) - { - // already checked? - } - - @Override - protected void doGet(HttpAction action) - { - MediaType mediaType = HttpAction.contentNegotationQuads(action) ; - ServletOutputStream output ; - try { output = action.response.getOutputStream() ; } - catch (IOException ex) { errorOccurred(ex) ; output = null ; } - - TypedOutputStream out = new TypedOutputStream(output, mediaType) ; - Lang lang = RDFLanguages.contentTypeToLang(mediaType.getContentType()) ; - if ( lang == null ) - lang = RDFLanguages.TRIG ; - - if ( action.verbose ) - log.info(format("[%d] Get: Content-Type=%s, Charset=%s => %s", - action.id, mediaType.getContentType(), mediaType.getCharset(), lang.getName())) ; - if ( ! RDFLanguages.isQuads(lang) ) - errorBadRequest("Not a quads format: "+mediaType) ; - - action.beginRead() ; - try { - DatasetGraph dsg = action.getActiveDSG() ; - RDFDataMgr.write(out, dsg, lang) ; - success(action) ; - } finally { action.endRead() ; } - } - - @Override - protected void doOptions(HttpAction action) - { - action.response.setHeader(HttpNames.hAllow, "GET, HEAD, OPTIONS") ; - action.response.setHeader(HttpNames.hContentLengh, "0") ; - success(action) ; - } - - @Override - protected void doHead(HttpAction action) - { - action.beginRead() ; - try { - MediaType mediaType = HttpAction.contentNegotationQuads(action) ; - success(action) ; - } finally { action.endRead() ; } - } - - static int counter = 0 ; - @Override - protected void doPost(HttpAction action) - { - if ( ! action.getDatasetRef().allowDatasetUpdate ) - errorMethodNotAllowed("POST") ; - - // Graph Store Protocol mode - POST triples to dataset causes - // a new graph to be created and the new URI returned via Location. - // Normally off. - // When off, POST of triples goes to default graph. - boolean gspMode = Fuseki.graphStoreProtocolPostCreate ; - - // Code to pass the GSP test suite. - // Not necessarily good code. - String x = action.request.getContentType() ; - if ( x == null ) - errorBadRequest("Content-type required for data format") ; - - MediaType mediaType = MediaType.create(x) ; - Lang lang = RDFLanguages.contentTypeToLang(mediaType.getContentType()) ; - if ( lang == null ) - lang = RDFLanguages.TRIG ; - - if ( action.verbose ) - log.info(format("[%d] Post: Content-Type=%s, Charset=%s => %s", - action.id, mediaType.getContentType(), mediaType.getCharset(), lang.getName())) ; - - if ( RDFLanguages.isQuads(lang) ) - doPostQuads(action, lang) ; - else if ( gspMode && RDFLanguages.isTriples(lang) ) - doPostTriplesGSP(action, lang) ; - else if ( RDFLanguages.isTriples(lang) ) - doPostTriples(action, lang) ; - else - errorBadRequest("Not a triples or quads format: "+mediaType) ; - } - - protected void doPostQuads(HttpAction action, Lang lang) - { - action.beginWrite() ; - try { - String name = action.request.getRequestURL().toString() ; - DatasetGraph dsg = action.getActiveDSG() ; - StreamRDF dest = StreamRDFLib.dataset(dsg) ; - ReaderRIOT reader = RDFDataMgr.createReader(lang) ; - reader.read(action.request.getInputStream(), name, null, dest, null); - action.commit(); - success(action) ; - } catch (IOException ex) { action.abort() ; } - finally { action.endWrite() ; } - } - - - // POST triples to dataset -- send to default graph. - protected void doPostTriples(HttpAction action, Lang lang) - { - action.beginWrite() ; - try { - DatasetGraph dsg = action.getActiveDSG() ; - // This should not be anythign other than the datasets name via this route. - String name = action.request.getRequestURL().toString() ; - //log.info(format("[%d] ** Content-length: %d", action.id, action.request.getContentLength())) ; - Graph g = dsg.getDefaultGraph() ; - StreamRDF dest = StreamRDFLib.graph(g) ; - ReaderRIOT reader = RDFDataMgr.createReader(lang) ; - reader.read(action.request.getInputStream(), name, null, dest, null); - action.commit(); - success(action) ; - } catch (IOException ex) { action.abort() ; } - finally { action.endWrite() ; } - } - - protected void doPostTriplesGSP(HttpAction action, Lang lang) - { - action.beginWrite() ; - try { - DatasetGraph dsg = action.getActiveDSG() ; - //log.info(format("[%d] ** Content-length: %d", action.id, action.request.getContentLength())) ; - - String name = action.request.getRequestURL().toString() ; - if ( ! name.endsWith("/") ) - name = name+ "/" ; - name = name+(++counter) ; - Node gn = NodeFactory.createURI(name) ; - Graph g = dsg.getGraph(gn) ; - StreamRDF dest = StreamRDFLib.graph(g) ; - ReaderRIOT reader = RDFDataMgr.createReader(lang) ; - reader.read(action.request.getInputStream(), name, null, dest, null); - log.info(format("[%d] Location: %s", action.id, name)) ; - action.response.setHeader("Location", name) ; - action.commit(); - successCreated(action) ; - } catch (IOException ex) { action.abort() ; } - finally { action.endWrite() ; } - } - - @Override - protected void doDelete(HttpAction action) - { errorMethodNotAllowed("DELETE") ; } - - @Override - protected void doPut(HttpAction action) - { errorMethodNotAllowed("PUT") ; } - - @Override - protected void doPatch(HttpAction action) - { errorMethodNotAllowed("PATCH") ; } -} - http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseCallback.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseCallback.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseCallback.java deleted file mode 100644 index 1a78627..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseCallback.java +++ /dev/null @@ -1,24 +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.servlets ; - -public interface ResponseCallback -{ - public void callback(boolean successfulOperation) ; -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseModel.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseModel.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseModel.java deleted file mode 100644 index f2172f0..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseModel.java +++ /dev/null @@ -1,143 +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.servlets; - -import static org.apache.jena.fuseki.servlets.ServletBase.error ; -import static org.apache.jena.fuseki.servlets.ServletBase.errorBadRequest ; -import static org.apache.jena.fuseki.servlets.ServletBase.errorOccurred ; - -import java.util.HashMap ; -import java.util.Map ; - -import javax.servlet.ServletOutputStream ; -import javax.servlet.http.HttpServletRequest ; -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.riot.Lang ; -import org.apache.jena.riot.RDFDataMgr ; -import org.apache.jena.riot.RDFLanguages ; -import org.apache.jena.riot.WebContent ; -import org.apache.jena.web.HttpSC ; -import org.slf4j.Logger ; - -import com.hp.hpl.jena.rdf.model.Model ; - -public class ResponseModel -{ - private static Logger slog = ServletBase.log ; - - // Short names for "output=" - private static final String contentOutputJSONLD = "json-ld" ; - private static final String contentOutputJSONRDF = "json-rdf" ; - private static final String contentOutputJSON = "json" ; - private static final String contentOutputXML = "xml" ; - private static final String contentOutputText = "text" ; - private static final String contentOutputTTL = "ttl" ; - private static final String contentOutputNT = "nt" ; - - public static Map<String,String> shortNamesModel = new HashMap<String, String>() ; - static { - - // Some short names. keys are lowercase. - ResponseOps.put(shortNamesModel, contentOutputJSONLD, WebContent.contentTypeJSONLD) ; - ResponseOps.put(shortNamesModel, contentOutputJSONRDF, WebContent.contentTypeRDFJSON) ; - ResponseOps.put(shortNamesModel, contentOutputJSON, WebContent.contentTypeJSONLD) ; - ResponseOps.put(shortNamesModel, contentOutputXML, WebContent.contentTypeRDFXML) ; - ResponseOps.put(shortNamesModel, contentOutputText, WebContent.contentTypeTurtle) ; - ResponseOps.put(shortNamesModel, contentOutputTTL, WebContent.contentTypeTurtle) ; - ResponseOps.put(shortNamesModel, contentOutputNT, WebContent.contentTypeNTriples) ; - } - - public static void doResponseModel(HttpAction action, Model model) - { - HttpServletRequest request = action.request ; - HttpServletResponse response = action.response ; - - String mimeType = null ; // Header request type - - // TODO Use MediaType throughout. - MediaType i = ConNeg.chooseContentType(request, DEF.rdfOffer, DEF.acceptRDFXML) ; - if ( i != null ) - mimeType = i.getContentType() ; - - String outputField = ResponseOps.paramOutput(request, shortNamesModel) ; - if ( outputField != null ) - mimeType = outputField ; - - String writerMimeType = mimeType ; - - if ( mimeType == null ) - { - Fuseki.requestLog.warn("Can't find MIME type for response") ; - String x = WebLib.getAccept(request) ; - String msg ; - if ( x == null ) - msg = "No Accept: header" ; - else - msg = "Accept: "+x+" : Not understood" ; - error(HttpSC.NOT_ACCEPTABLE_406, msg) ; - } - - String contentType = mimeType ; - String charset = WebContent.charsetUTF8 ; - - String forceAccept = ResponseOps.paramForceAccept(request) ; - if ( forceAccept != null ) - { - contentType = forceAccept ; - charset = WebContent.charsetUTF8 ; - } - - Lang lang = RDFLanguages.contentTypeToLang(contentType) ; - if ( lang == null ) - errorBadRequest("Can't determine output content type: "+contentType) ; - -// if ( rdfw instanceof RDFXMLWriterI ) -// rdfw.setProperty("showXmlDeclaration", "true") ; - - // // Write locally to check it's possible. - // // Time/space tradeoff. - // try { - // OutputStream out = new NullOutputStream() ; - // RDFDataMgr.write(out, model, lang) ; - // IO.flush(out) ; - // } catch (JenaException ex) - // { - // SPARQL_ServletBase.errorOccurred(ex) ; - // } - - try { - ResponseResultSet.setHttpResponse(request, response, contentType, charset) ; - response.setStatus(HttpSC.OK_200) ; - ServletOutputStream out = response.getOutputStream() ; - RDFDataMgr.write(out, model, lang) ; - out.flush() ; - } - catch (Exception ex) { - slog.info("Exception while writing the response model: "+ex.getMessage(), ex) ; - errorOccurred("Exception while writing the response model: "+ex.getMessage(), ex) ; - } - } -} - http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java deleted file mode 100644 index 62ad6d5..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseOps.java +++ /dev/null @@ -1,94 +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.servlets; - -import java.io.IOException ; -import java.util.Locale ; -import java.util.Map ; - -import javax.servlet.http.HttpServletRequest ; - -import org.apache.jena.fuseki.HttpNames ; - -public class ResponseOps -{ - // Helpers - public static void put(Map<String, String> map, String key, String value) - { - map.put(key.toLowerCase(Locale.ROOT), value) ; - } - - public static boolean isEOFexception(IOException ioEx) - { - if ( ioEx.getClass().getName().equals("org.mortbay.jetty.EofException eofEx") ) - return true ; - if ( ioEx instanceof java.io.EOFException ) - return true ; - return false ; - } - - public static String paramForceAccept(HttpServletRequest request) - { - String x = fetchParam(request, HttpNames.paramForceAccept) ; - return x ; - } - - public static String paramStylesheet(HttpServletRequest request) - { return fetchParam(request, HttpNames.paramStyleSheet) ; } - - public static String paramOutput(HttpServletRequest request, Map<String,String> map) - { - // Two names. - String x = fetchParam(request, HttpNames.paramOutput1) ; - if ( x == null ) - x = fetchParam(request, HttpNames.paramOutput2) ; - return expandShortName(x, map) ; - } - - public static String expandShortName(String str, Map<String,String> map) - { - if ( str == null ) - return null ; - // Force keys to lower case. See put() above. - String key = str.toLowerCase(Locale.ROOT) ; - String str2 = map.get(key) ; - if ( str2 == null ) - return str ; - return str2 ; - } - - public static String paramCallback(HttpServletRequest request) - { - return fetchParam(request, HttpNames.paramCallback) ; - } - - public static String fetchParam(HttpServletRequest request, String parameterName) - { - String value = request.getParameter(parameterName) ; - if ( value != null ) - { - value = value.trim() ; - if ( value.length() == 0 ) - value = null ; - } - return value ; - } - -} - http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java deleted file mode 100644 index c42378b..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/ResponseResultSet.java +++ /dev/null @@ -1,320 +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.servlets; - -import static java.lang.String.format ; -import static org.apache.jena.atlas.lib.Lib.equal ; -import static org.apache.jena.fuseki.servlets.ServletBase.errorBadRequest ; -import static org.apache.jena.fuseki.servlets.ServletBase.errorOccurred ; -import static org.apache.jena.fuseki.servlets.ServletBase.log ; - -import java.io.IOException ; -import java.util.HashMap ; -import java.util.Map ; - -import javax.servlet.ServletOutputStream ; -import javax.servlet.http.HttpServletRequest ; -import javax.servlet.http.HttpServletResponse ; - -import org.apache.commons.lang.StringUtils ; -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.riot.ResultSetMgr ; -import org.apache.jena.riot.WebContent ; -import org.apache.jena.riot.resultset.ResultSetLang ; -import org.apache.jena.web.HttpSC ; -import org.slf4j.Logger ; -import org.slf4j.LoggerFactory ; - -import com.hp.hpl.jena.query.QueryCancelledException ; -import com.hp.hpl.jena.query.ResultSet ; -import com.hp.hpl.jena.query.ResultSetFormatter ; -import com.hp.hpl.jena.sparql.core.Prologue ; - -/** This is the content negotiation for each kind of SPARQL query result */ -public class ResponseResultSet -{ - private static Logger xlog = LoggerFactory.getLogger(ResponseResultSet.class) ; - private static Logger slog = ServletBase.log ; - - // Short names for "output=" - private static final String contentOutputJSON = "json" ; - private static final String contentOutputXML = "xml" ; - private static final String contentOutputSPARQL = "sparql" ; - private static final String contentOutputText = "text" ; - private static final String contentOutputCSV = "csv" ; - private static final String contentOutputTSV = "tsv" ; - private static final String contentOutputThrift = "thrift" ; - - public static Map<String,String> shortNamesResultSet = new HashMap<String, String>() ; - static { - // Some short names. keys are lowercase. - ResponseOps.put(shortNamesResultSet, contentOutputJSON, WebContent.contentTypeResultsJSON) ; - ResponseOps.put(shortNamesResultSet, contentOutputSPARQL, WebContent.contentTypeResultsXML) ; - ResponseOps.put(shortNamesResultSet, contentOutputXML, WebContent.contentTypeResultsXML) ; - ResponseOps.put(shortNamesResultSet, contentOutputText, WebContent.contentTypeTextPlain) ; - ResponseOps.put(shortNamesResultSet, contentOutputCSV, WebContent.contentTypeTextCSV) ; - ResponseOps.put(shortNamesResultSet, contentOutputTSV, WebContent.contentTypeTextTSV) ; - ResponseOps.put(shortNamesResultSet, contentOutputThrift, WebContent.contentTypeResultsThrift) ; - } - - interface OutputContent { void output(ServletOutputStream out) ; } - - public static void doResponseResultSet(HttpAction action, Boolean booleanResult) - { - doResponseResultSet$(action, null, booleanResult, null, DEF.rsOfferTable) ; - } - - public static void doResponseResultSet(HttpAction action, ResultSet resultSet, Prologue qPrologue) - { - doResponseResultSet$(action, resultSet, null, qPrologue, DEF.rsOfferTable) ; - } - - // If we refactor the conneg into a single function, we can split boolean and result set handling. - - // One or the other argument must be null - private static void doResponseResultSet$(HttpAction action, - ResultSet resultSet, Boolean booleanResult, - Prologue qPrologue, - AcceptList contentTypeOffer) - { - HttpServletRequest request = action.request ; - HttpServletResponse response = action.response ; - long id = action.id ; - - if ( resultSet == null && booleanResult == null ) - { - xlog.warn("doResponseResult: Both result set and boolean result are null") ; - throw new FusekiException("Both result set and boolean result are null") ; - } - - if ( resultSet != null && booleanResult != null ) - { - xlog.warn("doResponseResult: Both result set and boolean result are set") ; - throw new FusekiException("Both result set and boolean result are set") ; - } - - String mimeType = null ; - MediaType i = ConNeg.chooseContentType(request, contentTypeOffer, DEF.acceptRSXML) ; - if ( i != null ) - mimeType = i.getContentType() ; - - // Override content type - // Does &output= override? - // Requested output type by the web form or &output= in the request. - String outputField = ResponseOps.paramOutput(request, shortNamesResultSet) ; // Expands short names - if ( outputField != null ) - mimeType = outputField ; - - String serializationType = mimeType ; // Choose the serializer based on this. - String contentType = mimeType ; // Set the HTTP respose header to this. - - // Stylesheet - change to application/xml. - final String stylesheetURL = ResponseOps.paramStylesheet(request) ; - if ( stylesheetURL != null && equal(serializationType,WebContent.contentTypeResultsXML) ) - contentType = WebContent.contentTypeXML ; - - // Force to text/plain? - String forceAccept = ResponseOps.paramForceAccept(request) ; - if ( forceAccept != null ) - contentType = WebContent.contentTypeTextPlain ; - - // Better : dispatch on MediaType - // Fuseki2 uses the SPARQL parser/write registry. - if ( equal(serializationType, WebContent.contentTypeResultsXML) ) - sparqlXMLOutput(action, contentType, resultSet, stylesheetURL, booleanResult) ; - else if ( equal(serializationType, WebContent.contentTypeResultsJSON) ) - jsonOutput(action, contentType, resultSet, booleanResult) ; - else if ( equal(serializationType, WebContent.contentTypeTextPlain) ) - textOutput(action, contentType, resultSet, qPrologue, booleanResult) ; - else if ( equal(serializationType, WebContent.contentTypeTextCSV) ) - csvOutput(action, contentType, resultSet, booleanResult) ; - else if (equal(serializationType, WebContent.contentTypeTextTSV) ) - tsvOutput(action, contentType, resultSet, booleanResult) ; - else if (equal(serializationType, WebContent.contentTypeResultsThrift) ) - thriftOutput(action, contentType, resultSet, booleanResult) ; - else - errorBadRequest("Can't determine output serialization: "+serializationType) ; - } - - - public static void setHttpResponse(HttpServletRequest httpRequest, - HttpServletResponse httpResponse, - String contentType, String charset) - { - // ---- Set up HTTP Response - // Stop caching (not that ?queryString URLs are cached anyway) - if ( true ) - { - httpResponse.setHeader("Cache-Control", "no-cache") ; - httpResponse.setHeader("Pragma", "no-cache") ; - } - // See: http://www.w3.org/International/O-HTTP-charset.html - if ( contentType != null ) - { - if ( charset != null && ! isXML(contentType) ) - contentType = contentType+"; charset="+charset ; - log.trace("Content-Type for response: "+contentType) ; - httpResponse.setContentType(contentType) ; - } - } - - private static boolean isXML(String contentType) - { - return contentType.equals(WebContent.contentTypeRDFXML) - || contentType.equals(WebContent.contentTypeResultsXML) - || contentType.equals(WebContent.contentTypeXML) ; - } - - private static void sparqlXMLOutput(HttpAction action, String contentType, final ResultSet resultSet, final String stylesheetURL, final Boolean booleanResult) - { - OutputContent proc = - new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetFormatter.outputAsXML(out, resultSet, stylesheetURL) ; - if ( booleanResult != null ) - ResultSetFormatter.outputAsXML(out, booleanResult, stylesheetURL) ; - }} ; - output(action, contentType, null, proc) ; - } - - private static void jsonOutput(HttpAction action, String contentType, final ResultSet resultSet, final Boolean booleanResult) - { - OutputContent proc = new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetFormatter.outputAsJSON(out, resultSet) ; - if ( booleanResult != null ) - ResultSetFormatter.outputAsJSON(out, booleanResult ) ; - } - } ; - - try { - String callback = ResponseOps.paramCallback(action.request) ; - ServletOutputStream out = action.response.getOutputStream() ; - - if ( callback != null ) - { - callback = StringUtils.replaceChars(callback, "\r", "") ; - callback = StringUtils.replaceChars(callback, "\n", "") ; - out.print(callback) ; - out.println("(") ; - } - - output(action, contentType, WebContent.charsetUTF8, proc) ; - - if ( callback != null ) - out.println(")") ; - } catch (IOException ex) { errorOccurred(ex) ; } - } - - private static void textOutput(HttpAction action, String contentType, final ResultSet resultSet, final Prologue qPrologue, final Boolean booleanResult) - { - // Text is not streaming. - OutputContent proc = new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetFormatter.out(out, resultSet, qPrologue) ; - if ( booleanResult != null ) - ResultSetFormatter.out(out, booleanResult ) ; - } - }; - - output(action, contentType, WebContent.charsetUTF8, proc) ; - } - - private static void csvOutput(HttpAction action, String contentType, final ResultSet resultSet, final Boolean booleanResult) { - OutputContent proc = new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetFormatter.outputAsCSV(out, resultSet) ; - if ( booleanResult != null ) - ResultSetFormatter.outputAsCSV(out, booleanResult ) ; - } - } ; - output(action, contentType, WebContent.charsetUTF8, proc) ; - } - - private static void tsvOutput(HttpAction action, String contentType, final ResultSet resultSet, final Boolean booleanResult) { - OutputContent proc = new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetFormatter.outputAsTSV(out, resultSet) ; - if ( booleanResult != null ) - ResultSetFormatter.outputAsTSV(out, booleanResult ) ; - } - } ; - output(action, contentType, WebContent.charsetUTF8, proc) ; - } - - private static void thriftOutput(HttpAction action, String contentType, final ResultSet resultSet, final Boolean booleanResult) { - OutputContent proc = new OutputContent(){ - @Override - public void output(ServletOutputStream out) - { - if ( resultSet != null ) - ResultSetMgr.write(out, resultSet, ResultSetLang.SPARQLResultSetThrift) ; - if ( booleanResult != null ) - slog.error("Can't write boolen result in thrift") ; - } - } ; - output(action, contentType, WebContent.charsetUTF8, proc) ; - } - - private static void output(HttpAction action, String contentType, String charset, OutputContent proc) - { - try { - setHttpResponse(action.request, action.response, contentType, charset) ; - action.response.setStatus(HttpSC.OK_200) ; - ServletOutputStream out = action.response.getOutputStream() ; - try - { - proc.output(out) ; - out.flush() ; - } catch (QueryCancelledException ex) { - // Bother. Status code 200 already sent. - slog.info(format("[%d] Query Cancelled - results truncated (but 200 already sent)", action.id)) ; - out.println() ; - out.println("## Query cancelled due to timeout during execution ##") ; - out.println("## **** Incomplete results **** ##") ; - out.flush() ; - // No point raising an exception - 200 was sent already. - //errorOccurred(ex) ; - } - // Includes client gone. - } catch (IOException ex) - { errorOccurred(ex) ; } - // Do not call httpResponse.flushBuffer(); here - Jetty closes the stream if it is a gzip stream - // then the JSON callback closing details can't be added. - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Protocol.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Protocol.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Protocol.java deleted file mode 100644 index ed57a37..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Protocol.java +++ /dev/null @@ -1,101 +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.servlets; - -import static org.apache.jena.fuseki.HttpNames.paramDefaultGraphURI ; -import static org.apache.jena.fuseki.HttpNames.paramNamedGraphURI ; - -import java.util.Arrays ; -import java.util.Collections ; -import java.util.List ; - -import javax.servlet.http.HttpServletRequest ; - -import org.apache.jena.atlas.iterator.Filter ; -import org.apache.jena.atlas.iterator.Iter ; -import org.apache.jena.atlas.lib.Lib ; - -import com.hp.hpl.jena.query.Query ; -import com.hp.hpl.jena.query.QueryParseException ; -import com.hp.hpl.jena.sparql.core.DatasetDescription ; - -/** Support for the SPARQL protocol (SPARQL Query, SPARQL Update) - */ -public abstract class SPARQL_Protocol extends SPARQL_ServletBase -{ - protected SPARQL_Protocol() { super() ; } - - protected static String messageForQPE(QueryParseException ex) - { - if ( ex.getMessage() != null ) - return ex.getMessage() ; - if ( ex.getCause() != null ) - return Lib.classShortName(ex.getCause().getClass()) ; - return null ; - } - - protected static DatasetDescription getDatasetDescription(HttpAction action) - { - List<String> graphURLs = toStrList(action.request.getParameterValues(paramDefaultGraphURI)) ; - List<String> namedGraphs = toStrList(action.request.getParameterValues(paramNamedGraphURI)) ; - - graphURLs = removeEmptyValues(graphURLs) ; - namedGraphs = removeEmptyValues(namedGraphs) ; - - if ( graphURLs.size() == 0 && namedGraphs.size() == 0 ) - return null ; - return DatasetDescription.create(graphURLs, namedGraphs) ; - } - - protected static DatasetDescription getDatasetDescription(Query query) - { - return DatasetDescription.create(query) ; - } - - private static List<String> toStrList(String[] array) - { - if ( array == null ) - return Collections.emptyList() ; - return Arrays.asList(array) ; - } - - private static List<String> removeEmptyValues(List<String> list) - { - return Iter.iter(list).filter(acceptNonEmpty).toList() ; - } - - private static Filter<String> acceptNonEmpty = new Filter<String>(){ - @Override - public boolean accept(String item) - { - return item != null && item.length() != 0 ; - } - } ; - - protected static int countParamOccurences(HttpServletRequest request, String param) - { - String[] x = request.getParameterValues(param) ; - if ( x == null ) - return 0 ; - return x.length ; - } - - -} - http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java deleted file mode 100644 index 06f8340..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Query.java +++ /dev/null @@ -1,387 +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.servlets; - -import static java.lang.String.format ; -import static org.apache.jena.fuseki.HttpNames.* ; -import static org.apache.jena.fuseki.server.CounterName.QueryExecErrors ; -import static org.apache.jena.fuseki.server.CounterName.QueryTimeouts ; -import static org.apache.jena.fuseki.server.CounterName.RequestsBad ; - -import java.io.IOException ; -import java.io.InputStream ; -import java.util.* ; - -import javax.servlet.http.HttpServletRequest ; -import javax.servlet.http.HttpServletResponse ; - -import org.apache.jena.atlas.RuntimeIOException ; -import org.apache.jena.atlas.io.IO ; -import org.apache.jena.atlas.io.IndentedLineBuffer ; -import org.apache.jena.atlas.web.ContentType ; -import org.apache.jena.fuseki.FusekiException ; -import org.apache.jena.fuseki.FusekiLib ; -import org.apache.jena.fuseki.HttpNames ; -import org.apache.jena.riot.WebContent ; -import org.apache.jena.riot.web.HttpOp ; -import org.apache.jena.web.HttpSC ; - -import com.hp.hpl.jena.query.* ; -import com.hp.hpl.jena.rdf.model.Model ; -import com.hp.hpl.jena.sparql.core.Prologue ; -import com.hp.hpl.jena.sparql.resultset.SPARQLResult ; - -/** - * Handles SPARQL Query requests. - */ -public abstract class SPARQL_Query extends SPARQL_Protocol -{ - public SPARQL_Query() { super() ; } - - // Choose REST verbs to support. - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - { doCommon(request, response) ; } - - // HEAD - - @Override - protected void doOptions(HttpServletRequest request, HttpServletResponse response) - { - setCommonHeadersForOptions(response) ; - response.setHeader(HttpNames.hAllow, "GET,OPTIONS,POST"); - response.setHeader(HttpNames.hContentLengh, "0") ; - } - - @Override - protected final void perform(HttpAction action) - { - // GET - if ( action.request.getMethod().equals(HttpNames.METHOD_GET) ) { - executeWithParameter(action) ; - return ; - } - - ContentType ct = FusekiLib.getContentType(action) ; - if ( ct == null ) { - // Validation check it's POST with ?query= - executeWithParameter(action) ; - return ; - } - - String incoming = ct.getContentType() ; - // POST application/sparql-query - if (WebContent.contentTypeSPARQLQuery.equals(incoming)) { - executeBody(action) ; - return ; - } - // POST application/x-www-form-url - if (WebContent.contentTypeHTMLForm.equals(incoming)) { - executeWithParameter(action) ; - return ; - } - - error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Bad content type: "+incoming) ; - } - - // All the params we support - - protected static List<String> allParams = Arrays.asList(paramQuery, - paramDefaultGraphURI, paramNamedGraphURI, - paramQueryRef, - paramStyleSheet, - paramAccept, - paramOutput1, paramOutput2, - paramCallback, - paramForceAccept, - paramTimeout) ; - - @Override - protected void validate(HttpAction action) - { - String method = action.request.getMethod().toUpperCase(Locale.ROOT) ; - - if ( ! HttpNames.METHOD_POST.equals(method) && ! HttpNames.METHOD_GET.equals(method) ) - errorMethodNotAllowed("Not a GET or POST request") ; - - if ( HttpNames.METHOD_GET.equals(method) && action.request.getQueryString() == null ) - { - warning("Service Description / SPARQL Query / "+action.request.getRequestURI()) ; - errorNotFound("Service Description: "+action.request.getRequestURI()) ; - } - - // Use of the dataset describing parameters is check later. - try { - validateParams(action.request, allParams) ; - validateRequest(action) ; - } catch (ActionErrorException ex) { - throw ex ; - } - // Query not yet parsed. - } - - /** - * Validate the request after checking HTTP method and HTTP Parameters. - * @param action HTTP Action - */ - protected abstract void validateRequest(HttpAction action) ; - - /** - * Helper method for validating request. - * @param request HTTP request - * @param params parameters in a collection of Strings - */ - protected void validateParams(HttpServletRequest request, Collection<String> params) - { - ContentType ct = FusekiLib.getContentType(request) ; - boolean mustHaveQueryParam = true ; - if ( ct != null ) - { - String incoming = ct.getContentType() ; - - if ( WebContent.contentTypeSPARQLQuery.equals(incoming) ) - { - mustHaveQueryParam = false ; - //error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Unofficial "+WebContent.contentTypeSPARQLQuery+" not supported") ; - } - else if ( WebContent.contentTypeHTMLForm.equals(incoming) ) {} - else - error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Unsupported: "+incoming) ; - } - - // GET/POST of a form at this point. - - if ( mustHaveQueryParam ) - { - int N = countParamOccurences(request, paramQuery) ; - - if ( N == 0 ) errorBadRequest("SPARQL Query: No 'query=' parameter") ; - if ( N > 1 ) errorBadRequest("SPARQL Query: Multiple 'query=' parameters") ; - - // application/sparql-query does not use a query param. - String queryStr = request.getParameter(HttpNames.paramQuery) ; - - if ( queryStr == null ) - errorBadRequest("SPARQL Query: No query specified (no 'query=' found)") ; - if ( queryStr.isEmpty() ) - errorBadRequest("SPARQL Query: Empty query string") ; - } - - if ( params != null ) - { - Enumeration<String> en = request.getParameterNames() ; - for ( ; en.hasMoreElements() ; ) - { - String name = en.nextElement() ; - if ( ! params.contains(name) ) - warning("SPARQL Query: Unrecognize request parameter (ignored): "+name) ; - } - } - } - - private void executeWithParameter(HttpAction action) - { - String queryString = action.request.getParameter(paramQuery) ; - execute(queryString, action) ; - } - - private void executeBody(HttpAction action) - { - String queryString = null ; - try { - InputStream input = action.request.getInputStream() ; - queryString = IO.readWholeFileAsUTF8(input) ; - } - catch (IOException ex) { errorOccurred(ex) ; } - execute(queryString, action) ; - } - - private void execute(String queryString, HttpAction action) - { - String queryStringLog = formatForLog(queryString) ; - if ( action.verbose ) - log.info(format("[%d] Query = \n%s", action.id, queryString)); - else - log.info(format("[%d] Query = %s", action.id, queryStringLog)); - - Query query = null ; - try { - // NB syntax is ARQ (a superset of SPARQL) - query = QueryFactory.create(queryString, "http://example/query-base", Syntax.syntaxARQ) ; - queryStringLog = formatForLog(query) ; - validateQuery(action, query) ; - } catch (ActionErrorException ex) { - incCounter(action.srvRef, RequestsBad) ; - throw ex ; - } catch (QueryParseException ex) { - incCounter(action.srvRef, RequestsBad) ; - errorBadRequest("Parse error: \n" + queryString + "\n\r" + messageForQPE(ex)) ; - } catch (RuntimeIOException ex) { - errorBadRequest("Runtime IO Exception: \n" + queryString + "\n\r" + ex.getMessage()) ; - } - // Should not happen. - catch (QueryException ex) { - errorBadRequest("Error: \n" + queryString + "\n\r" + ex.getMessage()) ; - } - - // Assumes finished whole thing by end of sendResult. - action.beginRead() ; - try { - Dataset dataset = decideDataset(action, query, queryStringLog) ; - try(QueryExecution qExec = createQueryExecution(query, dataset)) { - SPARQLResult result = executeQuery(action, qExec, query, queryStringLog) ; - // Deals with exceptions itself. - sendResults(action, result, query.getPrologue()) ; - } - } catch (QueryCancelledException ex) { - // Additional counter information. - incCounter(action.srvRef, QueryTimeouts) ; - throw ex ; - } catch (RuntimeIOException ex) { - incCounter(action.srvRef, QueryExecErrors) ; - throw ex ; - } catch (QueryExecException ex) { - // Additional counter information. - incCounter(action.srvRef, QueryExecErrors) ; - throw ex ; - } finally { - action.endRead() ; - } - } - - /** - * Check the query, throwing ActionErrorException when not valid, or calling super#error. - * @param action HTTP Action - * @param query the Query - */ - protected abstract void validateQuery(HttpAction action, Query query) ; - - protected QueryExecution createQueryExecution(Query query, Dataset dataset) - { - return QueryExecutionFactory.create(query, dataset) ; - } - - protected SPARQLResult executeQuery(HttpAction action, QueryExecution qExec, Query query, String queryStringLog) - { - setAnyTimeouts(qExec, action); - - if ( query.isSelectType() ) - { - ResultSet rs = qExec.execSelect() ; - - // Force some query execution now. - // - // If the timeout-first-row goes off, the output stream has not - // been started so the HTTP error code is sent. - - rs.hasNext() ; - - // If we wanted perfect query time cancellation, we could consume the result now - // to see if the timeout-end-of-query goes off. - - //rs = ResultSetFactory.copyResults(rs) ; - - log.info(format("[%d] exec/select", action.id)) ; - return new SPARQLResult(rs) ; - } - - if ( query.isConstructType() ) - { - Model model = qExec.execConstruct() ; - log.info(format("[%d] exec/construct", action.id)) ; - return new SPARQLResult(model) ; - } - - if ( query.isDescribeType() ) - { - Model model = qExec.execDescribe() ; - log.info(format("[%d] exec/describe",action.id)) ; - return new SPARQLResult(model) ; - } - - if ( query.isAskType() ) - { - boolean b = qExec.execAsk() ; - log.info(format("[%d] exec/ask",action.id)) ; - return new SPARQLResult(b) ; - } - - errorBadRequest("Unknown query type - "+queryStringLog) ; - return null ; - } - - private void setAnyTimeouts(QueryExecution qexec, HttpAction action) { - if (!(action.getDatasetRef().allowTimeoutOverride)) - return; - - long desiredTimeout = Long.MAX_VALUE; - String timeoutHeader = action.request.getHeader("Timeout"); - String timeoutParameter = action.request.getParameter("timeout"); - if (timeoutHeader != null) { - try { - desiredTimeout = (int) Float.parseFloat(timeoutHeader) * 1000; - } catch (NumberFormatException e) { - throw new FusekiException("Timeout header must be a number", e); - } - } else if (timeoutParameter != null) { - try { - desiredTimeout = (int) Float.parseFloat(timeoutParameter) * 1000; - } catch (NumberFormatException e) { - throw new FusekiException("timeout parameter must be a number", e); - } - } - - desiredTimeout = Math.min(action.getDatasetRef().maximumTimeoutOverride, desiredTimeout); - if (desiredTimeout != Long.MAX_VALUE) - qexec.setTimeout(desiredTimeout); - } - - protected abstract Dataset decideDataset(HttpAction action, Query query, String queryStringLog) ; - - protected void sendResults(HttpAction action, SPARQLResult result, Prologue qPrologue) - { - if ( result.isResultSet() ) - ResponseResultSet.doResponseResultSet(action, result.getResultSet(), qPrologue) ; - else if ( result.isGraph() ) - ResponseModel.doResponseModel(action, result.getModel()) ; - else if ( result.isBoolean() ) - ResponseResultSet.doResponseResultSet(action, result.getBooleanResult()) ; - else - errorOccurred("Unknown or invalid result type") ; - } - - private String formatForLog(Query query) - { - IndentedLineBuffer out = new IndentedLineBuffer() ; - out.setFlatMode(true) ; - query.serialize(out) ; - return out.asString() ; - } - - private String getRemoteString(String queryURI) - { - return HttpOp.execHttpGetString(queryURI) ; - } - -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.java deleted file mode 100644 index 9e9df36..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryDataset.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.servlets; - -import com.hp.hpl.jena.query.Dataset ; -import com.hp.hpl.jena.query.DatasetFactory ; -import com.hp.hpl.jena.query.Query ; -import com.hp.hpl.jena.sparql.core.DatasetDescription ; -import com.hp.hpl.jena.sparql.core.DatasetGraph ; -import com.hp.hpl.jena.sparql.core.DynamicDatasets ; - -public class SPARQL_QueryDataset extends SPARQL_Query -{ - public SPARQL_QueryDataset(boolean verbose) { super() ; } - - public SPARQL_QueryDataset() - { this(false) ; } - - @Override - protected void validateRequest(HttpAction action) - { } - - @Override - protected void validateQuery(HttpAction action, Query query) - { } - - @Override - protected Dataset decideDataset(HttpAction action, Query query, String queryStringLog) - { - DatasetGraph dsg = action.getActiveDSG() ; - - // query.getDatasetDescription() ; - - // Protocol. - DatasetDescription dsDesc = getDatasetDescription(action) ; - if (dsDesc != null ) - { - //errorBadRequest("SPARQL Query: Dataset description in the protocol request") ; - dsg = DynamicDatasets.dynamicDataset(dsDesc, dsg, false) ; - } - - return DatasetFactory.create(dsg) ; - } -} http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java deleted file mode 100644 index a022e96..0000000 --- a/jena-fuseki/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_QueryGeneral.java +++ /dev/null @@ -1,143 +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.servlets; - -import static java.lang.String.format ; - -import java.util.List ; - -import org.apache.jena.atlas.lib.InternalErrorException ; -import org.apache.jena.fuseki.migrate.GraphLoadUtils ; -import org.apache.jena.riot.RiotException ; - -import com.hp.hpl.jena.query.Dataset ; -import com.hp.hpl.jena.query.DatasetFactory ; -import com.hp.hpl.jena.query.Query ; -import com.hp.hpl.jena.rdf.model.Model ; -import com.hp.hpl.jena.rdf.model.ModelFactory ; -import com.hp.hpl.jena.sparql.core.DatasetDescription ; - -public class SPARQL_QueryGeneral extends SPARQL_Query -{ - final static int MaxTriples = 100*1000 ; - - public SPARQL_QueryGeneral() { super() ; } - - @Override - protected void validateRequest(HttpAction action) {} - - @Override - protected void validateQuery(HttpAction action, Query query) {} - - @Override - protected String mapRequestToDataset(String uri) - { return null ; } - - @Override - protected Dataset decideDataset(HttpAction action, Query query, String queryStringLog) - { - DatasetDescription datasetDesc = getDatasetDescription(action) ; - if ( datasetDesc == null ) - datasetDesc = getDatasetDescription(query) ; - if ( datasetDesc == null ) - errorBadRequest("No dataset description in protocol request or in the query string") ; - - return datasetFromDescription(action, datasetDesc) ; - } - - /** - * Construct a Dataset based on a dataset description. - */ - - protected static Dataset datasetFromDescription(HttpAction action, DatasetDescription datasetDesc) - { - try { - if ( datasetDesc == null ) - return null ; - if ( datasetDesc.isEmpty() ) - return null ; - - List<String> graphURLs = datasetDesc.getDefaultGraphURIs() ; - List<String> namedGraphs = datasetDesc.getNamedGraphURIs() ; - - if ( graphURLs.size() == 0 && namedGraphs.size() == 0 ) - return null ; - - Dataset dataset = DatasetFactory.createMem() ; - // Look in cache for loaded graphs!! - - // ---- Default graph - { - Model model = ModelFactory.createDefaultModel() ; - for ( String uri : graphURLs ) - { - if ( uri == null || uri.equals("") ) - throw new InternalErrorException("Default graph URI is null or the empty string") ; - - try { - //TODO Clearup - RIOT integration. - GraphLoadUtils.loadModel(model, uri, MaxTriples) ; - log.info(format("[%d] Load (default graph) %s", action.id, uri)) ; - } catch (RiotException ex) { - log.info(format("[%d] Parsing error loading %s: %s", action.id, uri, ex.getMessage())) ; - errorBadRequest("Failed to load URL (parse error) "+uri+" : "+ex.getMessage()) ; - } catch (Exception ex) - { - log.info(format("[%d] Failed to load (default) %s: %s", action.id, uri, ex.getMessage())) ; - errorBadRequest("Failed to load URL "+uri) ; - } - } - dataset.setDefaultModel(model) ; - } - // ---- Named graphs - if ( namedGraphs != null ) - { - for ( String uri : namedGraphs ) - { - if ( uri == null || uri.equals("") ) - throw new InternalErrorException("Named graph URI is null or the empty string") ; - - try { - Model model = ModelFactory.createDefaultModel() ; - GraphLoadUtils.loadModel(model, uri, MaxTriples) ; - log.info(format("[%d] Load (named graph) %s", action.id, uri)) ; - dataset.addNamedModel(uri, model) ; - } catch (RiotException ex) { - log.info(format("[%d] Parsing error loading %s: %s", action.id, uri, ex.getMessage())) ; - errorBadRequest("Failed to load URL (parse error) "+uri+" : "+ex.getMessage()) ; - } catch (Exception ex) - { - log.info(format("[%d] Failed to load (named graph) %s: %s", action.id, uri, ex.getMessage())) ; - errorBadRequest("Failed to load URL "+uri) ; - } - } - } - - return dataset ; - - } - catch (ActionErrorException ex) { throw ex ; } - catch (Exception ex) - { - log.info(format("[%d] SPARQL parameter error: "+ex.getMessage(),action.id, ex)) ; - errorBadRequest("Parameter error: "+ex.getMessage()); - return null ; - } - } -}
