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 2015/03/05 16:36:41 UTC
[02/23] jena git commit: Rename folder jena-fuseki to jena-fuseki1
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
new file mode 100644
index 0000000..f16f634
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Update.java
@@ -0,0 +1,308 @@
+/*
+ * 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.Fuseki.requestLog ;
+import static org.apache.jena.fuseki.HttpNames.paramRequest ;
+import static org.apache.jena.fuseki.HttpNames.paramUpdate ;
+import static org.apache.jena.fuseki.HttpNames.paramUsingGraphURI ;
+import static org.apache.jena.fuseki.HttpNames.paramUsingNamedGraphURI ;
+import static org.apache.jena.fuseki.server.CounterName.UpdateExecErrors ;
+
+import java.io.ByteArrayInputStream ;
+import java.io.IOException ;
+import java.io.InputStream ;
+import java.util.Arrays ;
+import java.util.Collection ;
+import java.util.Enumeration ;
+import java.util.List ;
+
+import javax.servlet.ServletException ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.atlas.web.ContentType ;
+import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.HttpNames ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.riot.WebContent ;
+import org.apache.jena.riot.system.IRIResolver ;
+import org.apache.jena.web.HttpSC ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.graph.NodeFactory ;
+import com.hp.hpl.jena.query.QueryParseException ;
+import com.hp.hpl.jena.query.Syntax ;
+import com.hp.hpl.jena.sparql.modify.UsingList ;
+import com.hp.hpl.jena.update.UpdateAction ;
+import com.hp.hpl.jena.update.UpdateException ;
+import com.hp.hpl.jena.update.UpdateFactory ;
+import com.hp.hpl.jena.update.UpdateRequest ;
+
+public class SPARQL_Update extends SPARQL_Protocol
+{
+ // Base URI used to isolate parsing from the current directory of the server.
+ private static final String UpdateParseBase = "http://example/update-base/" ;
+ private static final IRIResolver resolver = IRIResolver.create(UpdateParseBase) ;
+
+ public SPARQL_Update()
+ { super() ; }
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ response.sendError(HttpSC.BAD_REQUEST_400, "Attempt to perform SPARQL update by GET. Use POST") ;
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ doCommon(request, response) ;
+ }
+
+ @Override
+ protected void doOptions(HttpServletRequest request, HttpServletResponse response)
+ {
+ setCommonHeadersForOptions(response) ;
+ response.setHeader(HttpNames.hAllow, "OPTIONS,POST");
+ response.setHeader(HttpNames.hContentLengh, "0") ;
+ }
+
+ @Override
+ protected void perform(HttpAction action)
+ {
+ // WebContent needs to migrate to using ContentType.
+ String ctStr ;
+ {
+ ContentType ct = FusekiLib.getContentType(action) ;
+ if ( ct == null )
+ ctStr = WebContent.contentTypeSPARQLUpdate ;
+ else
+ ctStr = ct.getContentType() ;
+ }
+
+ if (WebContent.contentTypeSPARQLUpdate.equals(ctStr))
+ {
+ executeBody(action) ;
+ return ;
+ }
+ if (WebContent.contentTypeHTMLForm.equals(ctStr))
+ {
+ executeForm(action) ;
+ return ;
+ }
+ error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Bad content type: " + action.request.getContentType()) ;
+ }
+
+ protected static List<String> paramsForm = Arrays.asList(paramRequest, paramUpdate,
+ paramUsingGraphURI, paramUsingNamedGraphURI) ;
+ protected static List<String> paramsPOST = Arrays.asList(paramUsingGraphURI, paramUsingNamedGraphURI) ;
+
+ @Override
+ protected void validate(HttpAction action)
+ {
+ HttpServletRequest request = action.request ;
+
+ if ( ! HttpNames.METHOD_POST.equalsIgnoreCase(request.getMethod()) )
+ errorMethodNotAllowed("SPARQL Update : use POST") ;
+
+ ContentType incoming = FusekiLib.getContentType(action) ;
+ String ctStr = ( incoming == null ) ? WebContent.contentTypeSPARQLUpdate : incoming.getContentType() ;
+ // ----
+
+ if ( WebContent.contentTypeSPARQLUpdate.equals(ctStr) )
+ {
+ String charset = request.getCharacterEncoding() ;
+ if ( charset != null && ! charset.equalsIgnoreCase(WebContent.charsetUTF8) )
+ errorBadRequest("Bad charset: "+charset) ;
+ validate(request, paramsPOST) ;
+ return ;
+ }
+
+ if ( WebContent.contentTypeHTMLForm.equals(ctStr) )
+ {
+ int x = countParamOccurences(request, paramUpdate) + countParamOccurences(request, paramRequest) ;
+ if ( x == 0 )
+ errorBadRequest("SPARQL Update: No 'update=' parameter") ;
+ if ( x != 1 )
+ errorBadRequest("SPARQL Update: Multiple 'update=' parameters") ;
+
+ String requestStr = request.getParameter(paramUpdate) ;
+ if ( requestStr == null )
+ requestStr = request.getParameter(paramRequest) ;
+ if ( requestStr == null )
+ errorBadRequest("SPARQL Update: No update= in HTML form") ;
+ validate(request, paramsForm) ;
+ return ;
+ }
+
+ error(HttpSC.UNSUPPORTED_MEDIA_TYPE_415, "Must be "+WebContent.contentTypeSPARQLUpdate+" or "+WebContent.contentTypeHTMLForm+" (got "+ctStr+")") ;
+ }
+
+ protected void validate(HttpServletRequest request, Collection<String> params)
+ {
+ if ( params != null )
+ {
+ Enumeration<String> en = request.getParameterNames() ;
+ for ( ; en.hasMoreElements() ; )
+ {
+ String name = en.nextElement() ;
+ if ( ! params.contains(name) )
+ warning("SPARQL Update: Unrecognize request parameter (ignored): "+name) ;
+ }
+ }
+ }
+
+ private void executeBody(HttpAction action)
+ {
+ InputStream input = null ;
+ try { input = action.request.getInputStream() ; }
+ catch (IOException ex) { errorOccurred(ex) ; }
+
+ if ( action.verbose )
+ {
+ // Verbose mode only .... capture request for logging (does not scale).
+ String requestStr = null ;
+ try { requestStr = IO.readWholeFileAsUTF8(input) ; }
+ catch (IOException ex) { IO.exception(ex) ; }
+ requestLog.info(format("[%d] Update = %s", action.id, formatForLog(requestStr))) ;
+
+ input = new ByteArrayInputStream(requestStr.getBytes());
+ requestStr = null;
+ }
+
+ execute(action, input) ;
+ successNoContent(action) ;
+ }
+
+ private void executeForm(HttpAction action)
+ {
+ String requestStr = action.request.getParameter(paramUpdate) ;
+ if ( requestStr == null )
+ requestStr = action.request.getParameter(paramRequest) ;
+
+ if ( action.verbose )
+ //requestLog.info(format("[%d] Form update = %s", action.id, formatForLog(requestStr))) ;
+ requestLog.info(format("[%d] Form update = \n%s", action.id, requestStr)) ;
+ // A little ugly because we are taking a copy of the string, but hopefully shouldn't be too big if we are in this code-path
+ // If we didn't want this additional copy, we could make the parser take a Reader in addition to an InputStream
+ byte[] b = StrUtils.asUTF8bytes(requestStr) ;
+ ByteArrayInputStream input = new ByteArrayInputStream(b);
+ requestStr = null; // free it early at least
+ execute(action, input);
+ successPage(action,"Update succeeded") ;
+ }
+
+ private void execute(HttpAction action, InputStream input)
+ {
+ UsingList usingList = processProtocol(action.request) ;
+
+ // If the dsg is transactional, then we can parse and execute the update in a streaming fashion.
+ // If it isn't, we need to read the entire update request before performing any updates, because
+ // we have to attempt to make the request atomic in the face of malformed queries
+ UpdateRequest req = null ;
+ if (!action.isTransactional())
+ {
+ try {
+ // TODO implement a spill-to-disk version of this
+ req = UpdateFactory.read(usingList, input, UpdateParseBase, Syntax.syntaxARQ);
+ }
+ catch (UpdateException ex) { errorBadRequest(ex.getMessage()) ; return ; }
+ catch (QueryParseException ex) { errorBadRequest(messageForQPE(ex)) ; return ; }
+ }
+
+ action.beginWrite() ;
+ try {
+ if (req == null )
+ UpdateAction.parseExecute(usingList, action.getActiveDSG(), input, UpdateParseBase, Syntax.syntaxARQ);
+ else
+ UpdateAction.execute(req, action.getActiveDSG()) ;
+ action.commit() ;
+ } catch (UpdateException ex) {
+ action.abort() ;
+ incCounter(action.srvRef, UpdateExecErrors) ;
+ errorOccurred(ex.getMessage()) ;
+ } catch (QueryParseException ex) {
+ action.abort() ;
+ // Counter inc'ed further out.
+ errorBadRequest(messageForQPE(ex)) ;
+ } catch (Throwable ex) {
+ if ( ! ( ex instanceof ActionErrorException ) )
+ {
+ try { action.abort() ; } catch (Exception ex2) {}
+ errorOccurred(ex.getMessage(), ex) ;
+ }
+ } finally { action.endWrite(); }
+ }
+
+ /* [It is an error to supply the using-graph-uri or using-named-graph-uri parameters
+ * when using this protocol to convey a SPARQL 1.1 Update request that contains an
+ * operation that uses the USING, USING NAMED, or WITH clause.]
+ *
+ * We will simply capture any using parameters here and pass them to the parser, which will be
+ * responsible for throwing an UpdateException if the query violates the above requirement,
+ * and will also be responsible for adding the using parameters to update queries that can
+ * accept them.
+ */
+ private UsingList processProtocol(HttpServletRequest request)
+ {
+ UsingList toReturn = new UsingList();
+
+ String[] usingArgs = request.getParameterValues(paramUsingGraphURI) ;
+ String[] usingNamedArgs = request.getParameterValues(paramUsingNamedGraphURI) ;
+ if ( usingArgs == null && usingNamedArgs == null )
+ return toReturn;
+ if ( usingArgs == null )
+ usingArgs = new String[0] ;
+ if ( usingNamedArgs == null )
+ usingNamedArgs = new String[0] ;
+ // Impossible.
+// if ( usingArgs.length == 0 && usingNamedArgs.length == 0 )
+// return ;
+
+ for (String nodeUri : usingArgs)
+ {
+ toReturn.addUsing(createNode(nodeUri));
+ }
+ for (String nodeUri : usingNamedArgs)
+ {
+ toReturn.addUsingNamed(createNode(nodeUri));
+ }
+
+ return toReturn;
+ }
+
+ private static Node createNode(String x)
+ {
+ try {
+ IRI iri = resolver.resolve(x) ;
+ return NodeFactory.createURI(iri.toString()) ;
+ } catch (Exception ex)
+ {
+ errorBadRequest("SPARQL Update: bad IRI: "+x) ;
+ return null ;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
new file mode 100644
index 0000000..d21855f
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SPARQL_Upload.java
@@ -0,0 +1,260 @@
+/*
+ * 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 java.io.InputStream ;
+import java.io.PrintWriter ;
+import java.util.zip.GZIPInputStream ;
+
+import javax.servlet.ServletException ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.commons.fileupload.FileItemIterator ;
+import org.apache.commons.fileupload.FileItemStream ;
+import org.apache.commons.fileupload.servlet.ServletFileUpload ;
+import org.apache.commons.fileupload.util.Streams ;
+import org.apache.jena.atlas.lib.Pair ;
+import org.apache.jena.atlas.web.ContentType ;
+import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.fuseki.HttpNames ;
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFLanguages ;
+import org.apache.jena.riot.lang.StreamRDFCounting ;
+import org.apache.jena.riot.system.* ;
+import org.apache.jena.web.HttpSC ;
+
+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.Quad ;
+import com.hp.hpl.jena.sparql.graph.GraphFactory ;
+
+public class SPARQL_Upload extends SPARQL_ServletBase
+{
+ private static ErrorHandler errorHandler = ErrorHandlerFactory.errorHandlerStd(log) ;
+
+ public SPARQL_Upload() {
+ super() ;
+ }
+
+ // Methods to respond to.
+ @Override
+ protected void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException
+ {
+ doCommon(request, response) ;
+ }
+
+ @Override
+ protected void doOptions(HttpServletRequest request, HttpServletResponse response)
+ {
+ setCommonHeadersForOptions(response) ;
+ response.setHeader(HttpNames.hAllow, "OPTIONS,POST");
+ response.setHeader(HttpNames.hContentLengh, "0") ;
+ }
+
+ @Override
+ protected void perform(HttpAction action)
+ {
+ // Only allows one file in the upload.
+ boolean isMultipart = ServletFileUpload.isMultipartContent(action.request);
+ if ( ! isMultipart )
+ error(HttpSC.BAD_REQUEST_400 , "Not a file upload") ;
+ long count = upload(action, "http://example/upload-base/") ;
+ try {
+ action.response.setContentType("text/html") ;
+ action.response.setStatus(HttpSC.OK_200);
+ PrintWriter out = action.response.getWriter() ;
+ out.println("<html>") ;
+ out.println("<head>") ;
+ out.println("</head>") ;
+ out.println("<body>") ;
+ out.println("<h1>Success</h1>");
+ out.println("<p>") ;
+ out.println("Triples = "+count + "\n");
+ out.println("<p>") ;
+ out.println("</p>") ;
+ out.println("<button onclick=\"timeFunction()\">Back to Fuseki</button>");
+ out.println("</p>") ;
+ out.println("<script type=\"text/javascript\">");
+ out.println("function timeFunction(){");
+ out.println("window.location.href = \"/fuseki.html\";}");
+ out.println("</script>");
+ out.println("</body>") ;
+ out.println("</html>") ;
+ out.flush() ;
+ success(action) ;
+ }
+ catch (Exception ex) { errorOccurred(ex) ; }
+ }
+
+ // Also used by SPARQL_REST
+ static public long upload(HttpAction action, String base)
+ {
+ if ( action.isTransactional() )
+ return uploadTxn(action, base) ;
+ else
+ return uploadNonTxn(action, base) ;
+ }
+
+ /** Non-transaction - buffer to a temporary graph so that parse errors
+ * are caught before inserting any data.
+ */
+ private static long uploadNonTxn(HttpAction action, String base) {
+ Pair<String, Graph> p = uploadWorker(action, base) ;
+ String graphName = p.getLeft() ;
+ Graph graphTmp = p.getRight() ;
+ long tripleCount = graphTmp.size() ;
+
+ log.info(format("[%d] Upload: Graph: %s (%d triple(s))",
+ action.id, graphName, tripleCount)) ;
+
+ Node gn = graphName.equals(HttpNames.valueDefault)
+ ? Quad.defaultGraphNodeGenerated
+ : NodeFactory.createURI(graphName) ;
+
+ action.beginWrite() ;
+ try {
+ FusekiLib.addDataInto(graphTmp, action.getActiveDSG(), gn) ;
+ action.commit() ;
+ return tripleCount ;
+ } catch (RuntimeException ex)
+ {
+ // If anything went wrong, try to backout.
+ try { action.abort() ; } catch (Exception ex2) {}
+ errorOccurred(ex.getMessage()) ;
+ return -1 ;
+ }
+ finally { action.endWrite() ; }
+ }
+
+ /** Transactional - we'd like data to go straight to the destination, with an abort on parse error.
+ * But file upload with a name means that the name can be after the data
+ * (it is in the Fuseki default pages).
+ * Use Graph Store protocol for bulk uploads.
+ * (It would be possible to process the incoming stream and see the graph name first.)
+ */
+ private static long uploadTxn(HttpAction action, String base) {
+ // We can't do better than the non-transaction approach.
+ return uploadNonTxn(action, base) ;
+ }
+
+ /** process an HTTP upload of RDF.
+ * We can't stream straight into a dataset because the graph name can be after the data.
+ * @return graph name and count
+ */
+
+ static private Pair<String, Graph> uploadWorker(HttpAction action, String base)
+ {
+ Graph graphTmp = GraphFactory.createDefaultGraph() ;
+ ServletFileUpload upload = new ServletFileUpload();
+ String graphName = null ;
+ long count = -1 ;
+
+ String name = null ;
+ ContentType ct = null ;
+ Lang lang = null ;
+
+ try {
+ FileItemIterator iter = upload.getItemIterator(action.request);
+ while (iter.hasNext()) {
+ FileItemStream item = iter.next();
+ String fieldName = item.getFieldName();
+ InputStream stream = item.openStream();
+ if (item.isFormField())
+ {
+ // Graph name.
+ String value = Streams.asString(stream, "UTF-8") ;
+ if ( fieldName.equals(HttpNames.paramGraph) )
+ {
+ graphName = value ;
+ if ( graphName != null && ! graphName.equals("") && ! graphName.equals(HttpNames.valueDefault) )
+ {
+ IRI iri = IRIResolver.parseIRI(value) ;
+ if ( iri.hasViolation(false) )
+ errorBadRequest("Bad IRI: "+graphName) ;
+ if ( iri.getScheme() == null )
+ errorBadRequest("Bad IRI: no IRI scheme name: "+graphName) ;
+ if ( iri.getScheme().equalsIgnoreCase("http") || iri.getScheme().equalsIgnoreCase("https"))
+ {
+ // Redundant??
+ if ( iri.getRawHost() == null )
+ errorBadRequest("Bad IRI: no host name: "+graphName) ;
+ if ( iri.getRawPath() == null || iri.getRawPath().length() == 0 )
+ errorBadRequest("Bad IRI: no path: "+graphName) ;
+ if ( iri.getRawPath().charAt(0) != '/' )
+ errorBadRequest("Bad IRI: Path does not start '/': "+graphName) ;
+ }
+ }
+ }
+ else if ( fieldName.equals(HttpNames.paramDefaultGraphURI) )
+ graphName = null ;
+ else
+ // Add file type?
+ log.info(format("[%d] Upload: Field=%s ignored", action.id, fieldName)) ;
+ } else {
+ // Process the input stream
+ name = item.getName() ;
+ if ( name == null || name.equals("") || name.equals("UNSET FILE NAME") )
+ errorBadRequest("No name for content - can't determine RDF syntax") ;
+
+ String contentTypeHeader = item.getContentType() ;
+ ct = ContentType.create(contentTypeHeader) ;
+
+ lang = RDFLanguages.contentTypeToLang(ct.getContentType()) ;
+
+ if ( lang == null ) {
+ lang = RDFLanguages.filenameToLang(name) ;
+
+ //JENA-600 filenameToLang() strips off certain extensions such as .gz and
+ //we need to ensure that if there was a .gz extension present we wrap the stream accordingly
+ if (name.endsWith(".gz"))
+ stream = new GZIPInputStream(stream);
+ }
+ if ( lang == null )
+ // Desperate.
+ lang = RDFLanguages.RDFXML ;
+
+ log.info(format("[%d] Upload: Filename: %s, Content-Type=%s, Charset=%s => %s",
+ action.id, name, ct.getContentType(), ct.getCharset(), lang.getName())) ;
+
+ StreamRDF x = StreamRDFLib.graph(graphTmp) ;
+ StreamRDFCounting dest = StreamRDFLib.count(x) ;
+ SPARQL_REST.parse(action, dest, stream, lang, base);
+ count = dest.count() ;
+ }
+ }
+
+ if ( graphName == null || graphName.equals("") )
+ graphName = HttpNames.valueDefault ;
+ return Pair.create(graphName, graphTmp) ;
+ }
+ catch (ActionErrorException ex) { throw ex ; }
+ catch (Exception ex) { errorOccurred(ex) ; return null ; }
+ }
+
+ @Override
+ protected void validate(HttpAction action)
+ {}
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
new file mode 100644
index 0000000..7a74fa9
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/ServletBase.java
@@ -0,0 +1,242 @@
+/*
+ * 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.io.PrintWriter ;
+import java.util.concurrent.atomic.AtomicLong ;
+
+import javax.servlet.http.HttpServlet ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.atlas.lib.StrUtils ;
+import org.apache.jena.fuseki.Fuseki ;
+import org.apache.jena.fuseki.HttpNames ;
+import org.apache.jena.web.HttpSC ;
+import org.slf4j.Logger ;
+
+/**
+ * An abstract HTTP Servlet. Contains implementation methods for setting the request status in a HTTP Action,
+ * and a mechanism to allocate unique ID's to new requests.
+ */
+public abstract class ServletBase extends HttpServlet
+{
+ protected static final Logger log = Fuseki.requestLog ;
+ public final boolean verboseLogging = Fuseki.verboseLogging ;
+ private static AtomicLong requestIdAlloc = new AtomicLong(0) ;
+
+ protected ServletBase() { }
+
+ /**
+ * Helper method which gets a unique request ID and appends it as a header to the response
+ * @param request HTTP Request
+ * @param response HTTP Response
+ * @return Request ID
+ */
+ protected long allocRequestId(HttpServletRequest request, HttpServletResponse response) {
+ long id = requestIdAlloc.incrementAndGet();
+ addRequestId(response, id);
+ return id;
+ }
+
+ /**
+ * Helper method for attaching a request ID to a response as a header
+ * @param response Response
+ * @param id Request ID
+ */
+ protected void addRequestId(HttpServletResponse response, long id) {
+ response.addHeader("Fuseki-Request-ID", Long.toString(id));
+ }
+
+ protected void responseSendError(HttpServletResponse response, int statusCode, String message)
+ {
+ try { response.sendError(statusCode, message) ; }
+ catch (IOException ex) { errorOccurred(ex) ; }
+ catch (IllegalStateException ex) { }
+ }
+
+ protected void responseSendError(HttpServletResponse response, int statusCode)
+ {
+ try { response.sendError(statusCode) ; }
+ catch (IOException ex) { errorOccurred(ex) ; }
+ }
+
+ /**
+ * Returns the HTTP request URL, appended with any additional URL parameters used.
+ *
+ * @param request HTTP request
+ * @return complete request URL
+ */
+ protected static String wholeRequestURL(HttpServletRequest request)
+ {
+ StringBuffer sb = request.getRequestURL() ;
+ String queryString = request.getQueryString() ;
+ if ( queryString != null )
+ {
+ sb.append("?") ;
+ sb.append(queryString) ;
+ }
+ return sb.toString() ;
+ }
+
+ protected static void successNoContent(HttpAction action)
+ {
+ success(action, HttpSC.NO_CONTENT_204);
+ }
+
+ protected static void success(HttpAction action)
+ {
+ success(action, HttpSC.OK_200);
+ }
+
+ protected static void successCreated(HttpAction action)
+ {
+ success(action, HttpSC.CREATED_201);
+ }
+
+ // When 404 is no big deal e.g. HEAD
+ protected static void successNotFound(HttpAction action)
+ {
+ success(action, HttpSC.NOT_FOUND_404) ;
+ }
+
+ //
+ protected static void success(HttpAction action, int httpStatusCode)
+ {
+ action.response.setStatus(httpStatusCode);
+ }
+
+ protected static void successPage(HttpAction action, String message)
+ {
+ try {
+ action.response.setContentType("text/html");
+ action.response.setStatus(HttpSC.OK_200);
+ PrintWriter out = action.response.getWriter() ;
+ out.println("<html>") ;
+ out.println("<head>") ;
+ out.println("</head>") ;
+ out.println("<body>") ;
+ out.println("<h1>Success</h1>");
+ if ( message != null )
+ {
+ out.println("<p>") ;
+ out.println(message) ;
+ out.println("</p>") ;
+ }
+ out.println("</body>") ;
+ out.println("</html>") ;
+ out.flush() ;
+ } catch (IOException ex) { errorOccurred(ex) ; }
+ }
+
+ protected static void warning(String string)
+ {
+ log.warn(string) ;
+ }
+
+ protected static void warning(String string, Throwable thorwable)
+ {
+ log.warn(string, thorwable) ;
+ }
+
+ protected static void errorBadRequest(String string)
+ {
+ error(HttpSC.BAD_REQUEST_400, string) ;
+ }
+
+ protected static void errorNotFound(String string)
+ {
+ error(HttpSC.NOT_FOUND_404, string) ;
+ }
+
+ protected static void errorNotImplemented(String msg)
+ {
+ error(HttpSC.NOT_IMPLEMENTED_501, msg) ;
+ }
+
+ protected static void errorMethodNotAllowed(String method)
+ {
+ error(HttpSC.METHOD_NOT_ALLOWED_405, "HTTP method not allowed: "+method) ;
+ }
+
+ protected static void errorForbidden(String msg)
+ {
+ if ( msg != null )
+ error(HttpSC.FORBIDDEN_403, msg) ;
+ else
+ error(HttpSC.FORBIDDEN_403, "Forbidden") ;
+ }
+
+ protected static void error(int statusCode)
+ {
+ throw new ActionErrorException(null, null, statusCode) ;
+ }
+
+
+ protected static void error(int statusCode, String string)
+ {
+ throw new ActionErrorException(null, string, statusCode) ;
+ }
+
+ protected static void errorOccurred(String message)
+ {
+ errorOccurred(message, null) ;
+ }
+
+ protected static void errorOccurred(Throwable ex)
+ {
+ errorOccurred(null, ex) ;
+ }
+
+ protected static void errorOccurred(String message, Throwable ex)
+ {
+ throw new ActionErrorException(ex, message, HttpSC.INTERNAL_SERVER_ERROR_500) ;
+ }
+
+ protected static String formatForLog(String string)
+ {
+ string = string.replace('\n', ' ') ;
+ string = string.replace('\r', ' ') ;
+ return string ;
+ }
+
+ static String varyHeaderSetting =
+ StrUtils.strjoin(",",
+ HttpNames.hAccept,
+ HttpNames.hAcceptEncoding,
+ HttpNames.hAcceptCharset ) ;
+
+ public static void setVaryHeader(HttpServletResponse httpResponse)
+ {
+ httpResponse.setHeader(HttpNames.hVary, varyHeaderSetting) ;
+ }
+
+ public static void setCommonHeadersForOptions(HttpServletResponse httpResponse)
+ {
+ httpResponse.setHeader(HttpNames.hAccessControlAllowHeaders, "X-Requested-With, Content-Type, Authorization") ;
+ setCommonHeaders(httpResponse) ;
+ }
+
+ public static void setCommonHeaders(HttpServletResponse httpResponse)
+ {
+ httpResponse.setHeader(HttpNames.hAccessControlAllowOrigin, "*") ;
+ httpResponse.setHeader(HttpNames.hServer, Fuseki.serverHttpName) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocity.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocity.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocity.java
new file mode 100644
index 0000000..7f5cad9
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocity.java
@@ -0,0 +1,78 @@
+/**
+ * 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.io.Writer ;
+import java.util.Map ;
+
+import org.apache.velocity.Template ;
+import org.apache.velocity.VelocityContext ;
+import org.apache.velocity.app.VelocityEngine ;
+import org.apache.velocity.exception.MethodInvocationException ;
+import org.apache.velocity.exception.ParseErrorException ;
+import org.apache.velocity.exception.ResourceNotFoundException ;
+import org.apache.velocity.runtime.RuntimeConstants ;
+import org.apache.velocity.runtime.log.LogChute ;
+import org.apache.velocity.runtime.log.NullLogChute ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+public class SimpleVelocity
+{
+ private static LogChute velocityLogChute = new NullLogChute() ;
+ private static Logger velocityLog = LoggerFactory.getLogger("Velocity");
+
+ /** Process a template */
+ public static void process(String base, String path, Writer out, Map<String, Object> params)
+ {
+ process(base, path, out, createContext(params)) ;
+ }
+
+ /** Process a template */
+ public static void process(String base, String path, Writer out, VelocityContext context)
+ {
+ VelocityEngine velocity = new VelocityEngine() ;
+ // Turn off logging - catch exceptions and log ourselves
+ velocity.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, velocityLogChute) ;
+ velocity.setProperty(RuntimeConstants.INPUT_ENCODING, "UTF-8") ;
+ velocity.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, base) ;
+ velocity.init() ;
+ try {
+ Template temp = velocity.getTemplate(path) ;
+ temp.merge(context, out) ;
+ out.flush();
+ }
+ catch (ResourceNotFoundException ex) { velocityLog.error("Resource not found: "+ex.getMessage()) ; }
+ catch (ParseErrorException ex) { velocityLog.error("Parse error ("+path+") : "+ex.getMessage()) ; }
+ catch (MethodInvocationException ex) { velocityLog.error("Method invocation exception ("+path+") : "+ex.getMessage()) ; }
+ catch (IOException ex) { velocityLog.warn("IOException", ex) ; }
+ }
+
+ public static VelocityContext createContext(Map<String, Object> params)
+ {
+ // Velocity requires a mutable map.
+ // Scala leads to immutable maps ... be safe and copy.
+ VelocityContext context = new VelocityContext() ;
+ for ( Map.Entry<String, Object> e : params.entrySet() )
+ context.put(e.getKey(), e.getValue()) ;
+ return context ;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocityServlet.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocityServlet.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocityServlet.java
new file mode 100644
index 0000000..8773eba
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/servlets/SimpleVelocityServlet.java
@@ -0,0 +1,178 @@
+/**
+ * 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.io.Writer ;
+import java.util.Map ;
+
+import javax.servlet.http.HttpServlet ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.velocity.VelocityContext ;
+import org.apache.velocity.app.VelocityEngine ;
+import org.apache.velocity.runtime.RuntimeConstants ;
+import org.apache.velocity.runtime.RuntimeServices ;
+import org.apache.velocity.runtime.log.LogChute ;
+import org.apache.velocity.runtime.log.NullLogChute ;
+import org.slf4j.Logger ;
+import org.slf4j.LoggerFactory ;
+
+
+/** Simple servlet that uses <a href="http://velocity.apache.org/">Velocity</a>
+ * to format pages. It isolates the use of velocity by taking a configuration map.
+ * Use with a servlet mapping of "*.vm" or some such extension.
+ */
+public class SimpleVelocityServlet extends HttpServlet
+{
+ //private static Logger log = LoggerFactory.getLogger(SimpleVelocityServlet.class) ;
+ /* Velocity logging
+ * Instead of internal velocity logging, we catch the exceptions,
+ * log the message ourselves. This gives a celaner log file without
+ * loosing information that the application could use.
+ */
+
+ private static Logger vlog = LoggerFactory.getLogger("Velocity") ;
+ private static LogChute velocityLog = new NullLogChute() ;
+ //private static LogChute velocityLog = new SimpleSLF4JLogChute(vlog) ;
+
+ private String docbase ;
+ private VelocityEngine velocity ;
+ private String functionsName = null ;
+ private final Map<String, Object> datamodel ;
+
+ public SimpleVelocityServlet(String base, Map<String, Object> datamodel)
+ {
+ this.docbase = base ;
+ this.datamodel = datamodel ;
+ velocity = new VelocityEngine();
+ // Turn off logging - catch exceptions and log ourselves
+ velocity.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, velocityLog) ;
+ velocity.setProperty( RuntimeConstants.INPUT_ENCODING, "UTF-8" ) ;
+ velocity.setProperty( RuntimeConstants.FILE_RESOURCE_LOADER_PATH, base) ;
+ velocity.init();
+ }
+
+ // See also
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse resp)
+ {
+ process(req, resp) ;
+ }
+
+ @Override
+ public void doPost(HttpServletRequest req, HttpServletResponse resp)
+ {
+ process(req, resp) ;
+ }
+
+ private void process(HttpServletRequest req, HttpServletResponse resp)
+ {
+ try
+ {
+ resp.setContentType("text/html") ;
+ resp.setCharacterEncoding("UTF-8") ;
+ Writer out = resp.getWriter() ;
+ String path = path(req) ;
+ VelocityContext vc = SimpleVelocity.createContext(datamodel) ;
+ vc.put("request", req) ;
+ SimpleVelocity.process(docbase, path, out, vc) ;
+ } catch (IOException ex)
+ {
+ vlog.warn("IOException", ex) ;
+ }
+ }
+
+ private String path(HttpServletRequest request)
+ {
+ String path = request.getPathInfo();
+ if (path != null) return path;
+ path = request.getServletPath();
+ if (path != null) return path;
+ return null ;
+ }
+
+ @Override
+ public String getServletInfo()
+ {
+ return "Lightweight Velocity Servlet";
+ }
+
+ /** Velocity logger to SLF4J */
+ static class SimpleSLF4JLogChute implements LogChute
+ {
+ // Uusally for debugging only.
+ private Logger logger ;
+
+ SimpleSLF4JLogChute( Logger log )
+ {
+ this.logger = log ;
+ }
+
+ @Override
+ public void init(RuntimeServices rs) throws Exception
+ { }
+
+ @Override
+ public void log(int level, String message)
+ {
+ if ( logger == null ) return ;
+ switch(level)
+ {
+ case LogChute.TRACE_ID : logger.trace(message) ; return ;
+ case LogChute.DEBUG_ID : logger.debug(message) ; return ;
+ case LogChute.INFO_ID : logger.info(message) ; return ;
+ case LogChute.WARN_ID : logger.warn(message) ; return ;
+ case LogChute.ERROR_ID : logger.error(message) ; return ;
+ }
+ }
+
+ @Override
+ public void log(int level, String message, Throwable t)
+ {
+ if ( logger == null ) return ;
+ // Forget the stack trace - velcoity internal - long - unhelpful to application.
+ t = null ;
+ switch (level)
+ {
+ case LogChute.TRACE_ID : logger.trace(message, t) ; return ;
+ case LogChute.DEBUG_ID : logger.debug(message, t) ; return ;
+ case LogChute.INFO_ID : logger.info(message, t) ; return ;
+ case LogChute.WARN_ID : logger.warn(message, t) ; return ;
+ case LogChute.ERROR_ID : logger.error(message, t) ; return ;
+ }
+ }
+
+ @Override
+ public boolean isLevelEnabled(int level)
+ {
+ switch(level)
+ {
+ case LogChute.TRACE_ID: return logger.isTraceEnabled() ;
+ case LogChute.DEBUG_ID: return logger.isDebugEnabled() ;
+ case LogChute.INFO_ID: return logger.isInfoEnabled() ;
+ case LogChute.WARN_ID: return logger.isWarnEnabled() ;
+ case LogChute.ERROR_ID: return logger.isErrorEnabled() ;
+ }
+ return true ;
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java
new file mode 100644
index 0000000..6105562
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java
@@ -0,0 +1,237 @@
+/*
+ * 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.validation;
+
+import static org.apache.jena.riot.SysRIOT.fmtMessage ;
+
+import java.io.IOException ;
+import java.io.PrintStream ;
+import java.io.Reader ;
+import java.io.StringReader ;
+
+import javax.servlet.ServletOutputStream ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.atlas.io.IO ;
+import org.apache.jena.atlas.lib.Sink ;
+import org.apache.jena.fuseki.FusekiLib ;
+import org.apache.jena.riot.Lang ;
+import org.apache.jena.riot.RDFLanguages ;
+import org.apache.jena.riot.RiotException ;
+import org.apache.jena.riot.RiotReader ;
+import org.apache.jena.riot.lang.LangRIOT ;
+import org.apache.jena.riot.system.ErrorHandler ;
+import org.apache.jena.riot.system.RiotLib ;
+import org.apache.jena.riot.system.StreamRDF ;
+import org.apache.jena.riot.system.StreamRDFLib ;
+import org.apache.jena.riot.tokens.Tokenizer ;
+import org.apache.jena.riot.tokens.TokenizerFactory ;
+
+import com.hp.hpl.jena.graph.Node ;
+import com.hp.hpl.jena.sparql.core.Quad ;
+import com.hp.hpl.jena.sparql.serializer.SerializationContext ;
+import com.hp.hpl.jena.sparql.util.FmtUtils ;
+
+public class DataValidator extends ValidatorBase
+{
+ public DataValidator()
+ { }
+
+ static final String paramLineNumbers = "linenumbers" ;
+ static final String paramFormat = "outputFormat" ;
+ static final String paramIndirection = "url" ;
+ static final String paramData = "data" ;
+ static final String paramSyntax = "languageSyntax" ;
+ //static final String paramSyntaxExtended = "extendedSyntax" ;
+
+ @Override
+ protected void execute(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ {
+ try {
+// if ( log.isInfoEnabled() )
+// log.info("data validation request") ;
+
+ Tokenizer tokenizer = createTokenizer(httpRequest, httpResponse) ;
+ if ( tokenizer == null )
+ return ;
+
+ String syntax = FusekiLib.safeParameter(httpRequest, paramSyntax) ;
+ if ( syntax == null || syntax.equals("") )
+ syntax = RDFLanguages.NQUADS.getName() ;
+
+ Lang language = RDFLanguages.shortnameToLang(syntax) ;
+ if ( language == null )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown syntax: "+syntax) ;
+ return ;
+ }
+
+ ServletOutputStream outStream = httpResponse.getOutputStream() ;
+ ErrorHandlerMsg errorHandler = new ErrorHandlerMsg(outStream) ;
+
+ PrintStream stdout = System.out ;
+ PrintStream stderr = System.err ;
+ System.setOut(new PrintStream(outStream)) ;
+ System.setErr(new PrintStream(outStream)) ;
+
+ // Headers
+ setHeaders(httpResponse) ;
+
+ outStream.println("<html>") ;
+ printHead(outStream, "Jena Data Validator Report") ;
+ outStream.println("<body>") ;
+
+ outStream.println("<h1>RIOT Parser Report</h1>") ;
+ outStream.println("<p>Line and column numbers refer to original input</p>") ;
+ outStream.println("<p> </p>") ;
+ try {
+ LangRIOT parser = setupParser(tokenizer, language, errorHandler, outStream) ;
+ startFixed(outStream) ;
+ RiotException exception = null ;
+ try {
+ parser.parse() ;
+ System.out.flush() ;
+ System.err.flush() ;
+ } catch (RiotException ex) { exception = ex ; }
+ } finally
+ {
+ finishFixed(outStream) ;
+ System.out.flush() ;
+ System.err.flush() ;
+ System.setOut(stdout) ;
+ System.setErr(stdout) ;
+ }
+
+ outStream.println("</body>") ;
+ outStream.println("</html>") ;
+ } catch (Exception ex)
+ {
+ serviceLog.warn("Exception in validationRequest",ex) ;
+ }
+ }
+
+ static final long LIMIT = 50000 ;
+
+
+ private LangRIOT setupParser(Tokenizer tokenizer, Lang language, ErrorHandler errorHandler, final ServletOutputStream outStream)
+ {
+ Sink<Quad> sink = new Sink<Quad>()
+ {
+ SerializationContext sCxt = new SerializationContext() ;
+ @Override
+ public void send(Quad quad)
+ {
+ // Clean up!
+ StringBuilder sb = new StringBuilder() ;
+
+ sb.append(formatNode(quad.getSubject())) ;
+ sb.append(" ") ;
+ sb.append(formatNode(quad.getPredicate())) ;
+ sb.append(" ") ;
+ sb.append(formatNode(quad.getObject())) ;
+
+ if ( ! quad.isTriple() )
+ {
+ sb.append(" ") ;
+ sb.append(formatNode(quad.getGraph())) ;
+ }
+
+ String $ = htmlQuote(sb.toString()) ;
+ try {
+ outStream.print($) ;
+ outStream.println(" .") ;
+ } catch (IOException ex) { IO.exception(ex) ; }
+ }
+ @Override
+ public void close() {}
+ @Override
+ public void flush() {}
+ String formatNode(Node n) { return FmtUtils.stringForNode(n, sCxt) ; }
+ } ;
+
+ StreamRDF dest = StreamRDFLib.sinkQuads(sink) ;
+ @SuppressWarnings("deprecation")
+ LangRIOT parser = RiotReader.createParser(tokenizer, language, null, dest) ;
+ // Don't resolve IRIs. Do checking.
+ parser.setProfile(RiotLib.profile(null, false, true, errorHandler)) ;
+ return parser ;
+ }
+
+ // Error handler that records messages
+ private static class ErrorHandlerMsg implements ErrorHandler
+ {
+ private ServletOutputStream out ;
+
+ ErrorHandlerMsg(ServletOutputStream out) { this.out = out ; }
+
+ @Override
+ public void warning(String message, long line, long col)
+ { output(message, line, col, "Warning", "warning") ; }
+
+ // Attempt to continue.
+ @Override
+ public void error(String message, long line, long col)
+ { output(message, line, col, "Error", "error") ; }
+
+ @Override
+ public void fatal(String message, long line, long col)
+ { output(message, line, col, "Fatal", "error") ; throw new RiotException(fmtMessage(message, line, col)) ; }
+
+ private void output(String message, long line, long col, String typeName, String className)
+ {
+ try {
+ String str = fmtMessage(message, line, col) ;
+ //String str = typeName+": "+message ;
+ str = htmlQuote(str) ;
+ out.print("<div class=\""+className+"\">") ;
+ out.print(str) ;
+ out.print("</div>") ;
+ } catch (IOException ex) { IO.exception(ex) ; }
+ }
+ }
+
+ private Tokenizer createTokenizer(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws Exception
+ {
+ Reader reader = null ;
+ String[] args = httpRequest.getParameterValues(paramData) ;
+ if ( args == null || args.length == 0 )
+ {
+ // Not a form?
+ reader = httpRequest.getReader() ;
+ }
+ else if ( args.length > 1 )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Too many parameters for '"+paramData+"='") ;
+ return null ;
+ }
+ else
+ {
+ reader = new StringReader(args[0]) ;
+ }
+
+ if ( reader == null )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Can't find data to validate") ;
+ return null ;
+ }
+
+ return TokenizerFactory.makeTokenizer(reader) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java
new file mode 100644
index 0000000..2972b49
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java
@@ -0,0 +1,99 @@
+/*
+ * 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.validation;
+
+import java.io.IOException ;
+import java.io.PrintStream ;
+import java.util.Iterator ;
+
+import javax.servlet.ServletOutputStream ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.iri.IRI ;
+import org.apache.jena.iri.IRIFactory ;
+import org.apache.jena.iri.Violation ;
+import org.apache.jena.riot.system.IRIResolver ;
+
+public class IRIValidator extends ValidatorBase
+{
+ public IRIValidator()
+ { }
+
+ static final String paramIRI = "iri" ;
+ //static IRIFactory iriFactory = IRIFactory.iriImplementation() ;
+ static IRIFactory iriFactory = IRIResolver.iriFactory ;
+
+ @Override
+ protected void execute(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ {
+ try {
+ String[] args = httpRequest.getParameterValues(paramIRI) ;
+ ServletOutputStream outStream = httpResponse.getOutputStream() ;
+ PrintStream stdout = System.out ;
+ PrintStream stderr = System.err ;
+ System.setOut(new PrintStream(outStream)) ;
+ System.setErr(new PrintStream(outStream)) ;
+
+ setHeaders(httpResponse) ;
+
+ outStream.println("<html>") ;
+ printHead(outStream, "Jena IRI Validator Report") ;
+ outStream.println("<body>") ;
+
+ outStream.println("<h1>IRI Report</h1>") ;
+
+ startFixed(outStream) ;
+
+ try {
+ boolean first = true ;
+ for ( String iriStr : args )
+ {
+ if ( ! first )
+ System.out.println() ;
+ first = false ;
+
+ IRI iri = iriFactory.create(iriStr) ;
+ System.out.println(iriStr + " ==> "+iri) ;
+ if ( iri.isRelative() )
+ System.out.println("Relative IRI: "+iriStr) ;
+
+ Iterator<Violation> vIter = iri.violations(true) ;
+ for ( ; vIter.hasNext() ; )
+ {
+ String str = vIter.next().getShortMessage() ;
+ str = htmlQuote(str) ;
+
+ System.out.println(str) ;
+ }
+ }
+ } finally
+ {
+ finishFixed(outStream) ;
+ System.out.flush() ;
+ System.err.flush() ;
+ System.setOut(stdout) ;
+ System.setErr(stdout) ;
+ }
+
+ outStream.println("</body>") ;
+ outStream.println("</html>") ;
+ } catch (IOException ex) {}
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java
new file mode 100644
index 0000000..75ad901
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java
@@ -0,0 +1,269 @@
+/*
+ * 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.validation;
+
+import java.io.IOException ;
+
+import javax.servlet.ServletOutputStream ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer ;
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.query.Query ;
+import com.hp.hpl.jena.query.QueryFactory ;
+import com.hp.hpl.jena.query.Syntax ;
+import com.hp.hpl.jena.sparql.ARQException ;
+import com.hp.hpl.jena.sparql.algebra.Algebra ;
+import com.hp.hpl.jena.sparql.algebra.Op ;
+import com.hp.hpl.jena.sparql.serializer.SerializationContext ;
+
+public class QueryValidator extends ValidatorBase
+{
+ public QueryValidator()
+ { }
+
+ static final String paramLineNumbers = "linenumbers" ;
+ static final String paramFormat = "outputFormat" ;
+ static final String paramQuery = "query" ;
+ static final String paramSyntax = "languageSyntax" ;
+ //static final String paramSyntaxExtended = "extendedSyntax" ;
+
+ @Override
+ protected void execute(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ {
+ try {
+// if ( log.isInfoEnabled() )
+// log.info("validation request") ;
+
+ String[] args = httpRequest.getParameterValues(paramQuery) ;
+
+ if ( args == null || args.length == 0 )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "No query parameter to validator") ;
+ return ;
+ }
+
+ if ( args.length > 1 )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Too many query parameters") ;
+ return ;
+ }
+
+ final String queryString = httpRequest.getParameter(paramQuery).replaceAll("(\r|\n| )*$", "") ;
+// queryString = queryString.replace("\r\n", "\n") ;
+// queryString.replaceAll("(\r|\n| )*$", "") ;
+
+ String querySyntax = httpRequest.getParameter(paramSyntax) ;
+ if ( querySyntax == null || querySyntax.equals("") )
+ querySyntax = "SPARQL" ;
+
+ Syntax language = Syntax.lookup(querySyntax) ;
+ if ( language == null )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown syntax: "+querySyntax) ;
+ return ;
+ }
+
+ String lineNumbersArg = httpRequest.getParameter(paramLineNumbers) ;
+
+ String a[] = httpRequest.getParameterValues(paramFormat) ;
+
+ boolean outputSPARQL = false ;
+ boolean outputPrefix = false ;
+ boolean outputAlgebra = false ;
+ boolean outputQuads = false ;
+ boolean outputOptimized = false ;
+ boolean outputOptimizedQuads = false ;
+
+ if ( a != null )
+ {
+ for ( String anA : a )
+ {
+ if ( anA.equals( "sparql" ) )
+ {
+ outputSPARQL = true;
+ }
+ if ( anA.equals( "prefix" ) )
+ {
+ outputPrefix = true;
+ }
+ if ( anA.equals( "algebra" ) )
+ {
+ outputAlgebra = true;
+ }
+ if ( anA.equals( "quads" ) )
+ {
+ outputQuads = true;
+ }
+ if ( anA.equals( "opt" ) )
+ {
+ outputOptimized = true;
+ }
+ if ( anA.equals( "optquads" ) )
+ {
+ outputOptimizedQuads = true;
+ }
+ }
+ }
+
+// if ( ! outputSPARQL && ! outputPrefix )
+// outputSPARQL = true ;
+
+ boolean lineNumbers = true ;
+
+ if ( lineNumbersArg != null )
+ lineNumbers = lineNumbersArg.equalsIgnoreCase("true") || lineNumbersArg.equalsIgnoreCase("yes") ;
+
+ // Headers
+ setHeaders(httpResponse) ;
+
+ ServletOutputStream outStream = httpResponse.getOutputStream() ;
+
+ outStream.println("<html>") ;
+
+ printHead(outStream, "SPARQL Query Validation Report") ;
+
+ outStream.println("<body>") ;
+ outStream.println("<h1>SPARQL Query Validator</h1>") ;
+ // Print query as received
+ {
+ outStream.println("<p>Input:</p>") ;
+ // Not Java's finest hour.
+ Content c = new Content(){
+ @Override
+ public void print(IndentedWriter out)
+ { out.print(queryString) ; }
+ } ;
+ output(outStream, c, lineNumbers) ;
+ }
+
+ // Attempt to parse it.
+ Query query = null ;
+ try {
+ query = QueryFactory.create(queryString, "http://example/base/", language) ;
+ } catch (ARQException ex)
+ {
+ // Over generous exception (should be QueryException)
+ // but this makes the code robust.
+ outStream.println("<p>Syntax error:</p>") ;
+ startFixed(outStream) ;
+ outStream.println(ex.getMessage()) ;
+ finishFixed(outStream) ;
+ }
+ catch (RuntimeException ex)
+ {
+ outStream.println("<p>Internal error:</p>") ;
+ startFixed(outStream) ;
+ outStream.println(ex.getMessage()) ;
+ finishFixed(outStream) ;
+ }
+
+ if ( query != null )
+ {
+ if ( outputSPARQL )
+ outputSyntax(outStream, query, lineNumbers) ;
+
+ if ( outputAlgebra )
+ outputAlgebra(outStream, query, lineNumbers) ;
+
+ if ( outputQuads )
+ outputAlgebraQuads(outStream, query, lineNumbers) ;
+
+ if ( outputOptimized )
+ outputAlgebraOpt(outStream, query, lineNumbers) ;
+
+ if ( outputOptimizedQuads )
+ outputAlgebraOptQuads(outStream, query, lineNumbers) ;
+ }
+
+ outStream.println("</body>") ;
+ outStream.println("</html>") ;
+
+ } catch (Exception ex)
+ {
+ serviceLog.warn("Exception in doGet",ex) ;
+ }
+ }
+
+ interface Content { void print(IndentedWriter out) ; }
+
+ private void outputSyntax(ServletOutputStream outStream, final Query query, boolean lineNumbers) throws IOException
+ {
+ outStream.println("<p>Formatted, parsed query:</p>") ;
+ Content c = new Content(){
+ @Override
+ public void print(IndentedWriter out)
+ { query.serialize(out) ; }
+ } ;
+ output(outStream, c, lineNumbers) ;
+ }
+
+ private void outputAlgebra(ServletOutputStream outStream, final Query query, boolean lineNumbers) throws IOException
+ {
+ outStream.println("<p>Algebra structure:</p>") ;
+ final Op op = Algebra.compile(query) ; // No optimization
+ output(outStream, query, op, lineNumbers) ;
+ }
+
+ private void outputAlgebraOpt(ServletOutputStream outStream, final Query query, boolean lineNumbers) throws IOException
+ {
+ outStream.println("<p>Alebgra, with general triple optimizations:</p>") ;
+ final Op op = Algebra.optimize(Algebra.compile(query)) ;
+ output(outStream, query, op, lineNumbers) ;
+ }
+
+ private void outputAlgebraQuads(ServletOutputStream outStream, final Query query, boolean lineNumbers) throws IOException
+ {
+ outStream.println("<p>Quad structure:</p>") ;
+ final Op op = Algebra.toQuadForm(Algebra.compile(query)) ;
+ output(outStream, query, op, lineNumbers) ;
+ }
+
+ private void outputAlgebraOptQuads(ServletOutputStream outStream, final Query query, boolean lineNumbers) throws IOException
+ {
+ outStream.println("<p>Alebgra, with general quads optimizations:</p>") ;
+ final Op op = Algebra.optimize(Algebra.toQuadForm(Algebra.compile(query))) ;
+ output(outStream, query, op, lineNumbers) ;
+ }
+
+ private void output(ServletOutputStream outStream, Query query, final Op op, boolean lineNumbers) throws IOException
+ {
+ final SerializationContext sCxt = new SerializationContext(query) ;
+ Content c = new Content(){
+ @Override
+ public void print(IndentedWriter out)
+ { op.output(out, sCxt) ; }
+ } ;
+ output(outStream, c , lineNumbers) ;
+ }
+
+ private void output(ServletOutputStream outStream, Content content, boolean lineNumbers) throws IOException
+ {
+ startFixed(outStream) ;
+ IndentedLineBuffer out = new IndentedLineBuffer(lineNumbers) ;
+ content.print(out) ;
+ out.flush() ;
+ String x = htmlQuote(out.asString()) ;
+ byte b[] = x.getBytes("UTF-8") ;
+ outStream.write(b) ;
+ finishFixed(outStream) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java
new file mode 100644
index 0000000..dd63de8
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java
@@ -0,0 +1,174 @@
+/*
+ * 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.validation;
+
+import java.io.IOException ;
+
+import javax.servlet.ServletOutputStream ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.atlas.io.IndentedLineBuffer ;
+import org.apache.jena.atlas.io.IndentedWriter ;
+
+import com.hp.hpl.jena.query.Syntax ;
+import com.hp.hpl.jena.sparql.ARQException ;
+import com.hp.hpl.jena.update.UpdateFactory ;
+import com.hp.hpl.jena.update.UpdateRequest ;
+
+public class UpdateValidator extends ValidatorBase
+{
+ public UpdateValidator()
+ { }
+
+ static final String paramLineNumbers = "linenumbers" ;
+ static final String paramFormat = "outputFormat" ;
+ static final String paramUpdate = "update" ;
+ static final String paramSyntax = "languageSyntax" ;
+ //static final String paramSyntaxExtended = "extendedSyntax" ;
+
+ @Override
+ protected void execute(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ {
+ try {
+// if ( log.isInfoEnabled() )
+// log.info("validation request") ;
+
+ String[] args = httpRequest.getParameterValues(paramUpdate) ;
+
+ if ( args == null || args.length == 0 )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "No update parameter to validator") ;
+ return ;
+ }
+
+ if ( args.length > 1 )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Too many update parameters") ;
+ return ;
+ }
+
+ final String updateString = httpRequest.getParameter(paramUpdate).replaceAll("(\r|\n| )*$", "") ;
+
+ String updateSyntax = httpRequest.getParameter(paramSyntax) ;
+ if ( updateSyntax == null || updateSyntax.equals("") )
+ updateSyntax = "SPARQL" ;
+
+ Syntax language = Syntax.lookup(updateSyntax) ;
+ if ( language == null )
+ {
+ httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Unknown syntax: "+updateSyntax) ;
+ return ;
+ }
+
+ String lineNumbersArg = httpRequest.getParameter(paramLineNumbers) ;
+ String a[] = httpRequest.getParameterValues(paramFormat) ;
+
+ // Currently default.
+ boolean outputSPARQL = true ;
+ boolean lineNumbers = true ;
+
+ if ( lineNumbersArg != null )
+ lineNumbers = lineNumbersArg.equalsIgnoreCase("true") || lineNumbersArg.equalsIgnoreCase("yes") ;
+
+ // Headers
+ setHeaders(httpResponse) ;
+
+ ServletOutputStream outStream = httpResponse.getOutputStream() ;
+
+ outStream.println("<html>") ;
+
+ printHead(outStream, "SPARQL Update Validation Report") ;
+
+ outStream.println("<body>") ;
+ outStream.println("<h1>SPARQL Update Validator</h1>") ;
+
+ // Print as received
+ {
+ outStream.println("<p>Input:</p>") ;
+ // Not Java's finest hour.
+ Content c = new Content(){
+ @Override
+ public void print(IndentedWriter out)
+ { out.print(updateString) ; }
+ } ;
+ output(outStream, c, lineNumbers) ;
+ }
+
+ // Attempt to parse it.
+ UpdateRequest request= null ;
+ try {
+ request = UpdateFactory.create(updateString, "http://example/base/", language) ;
+ } catch (ARQException ex)
+ {
+ // Over generous exception (should be QueryException)
+ // but this makes the code robust.
+ outStream.println("<p>Syntax error:</p>") ;
+ startFixed(outStream) ;
+ outStream.println(ex.getMessage()) ;
+ finishFixed(outStream) ;
+ }
+ catch (RuntimeException ex)
+ {
+ outStream.println("<p>Internal error:</p>") ;
+ startFixed(outStream) ;
+ outStream.println(ex.getMessage()) ;
+ finishFixed(outStream) ;
+ }
+
+ // Because we pass into anon inner classes
+ final UpdateRequest updateRequest = request ;
+
+ // OK? Pretty print
+ if ( updateRequest != null && outputSPARQL )
+ {
+ outStream.println("<p>Formatted, parsed update request:</p>") ;
+ Content c = new Content(){
+ @Override
+ public void print(IndentedWriter out)
+ {
+ updateRequest.output(out) ;
+ }
+
+ } ;
+ output(outStream, c, lineNumbers) ;
+ }
+ outStream.println("</body>") ;
+ outStream.println("</html>") ;
+
+ } catch (Exception ex)
+ {
+ serviceLog.warn("Exception in doGet",ex) ;
+ }
+ }
+
+ interface Content { void print(IndentedWriter out) ; }
+
+ private void output(ServletOutputStream outStream, Content content, boolean lineNumbers) throws IOException
+ {
+ startFixed(outStream) ;
+ IndentedLineBuffer out = new IndentedLineBuffer(lineNumbers) ;
+ content.print(out) ;
+ out.flush() ;
+ String x = htmlQuote(out.asString()) ;
+ byte b[] = x.getBytes("UTF-8") ;
+ outStream.write(b) ;
+ finishFixed(outStream) ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
new file mode 100644
index 0000000..61820f4
--- /dev/null
+++ b/jena-fuseki1/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java
@@ -0,0 +1,120 @@
+/*
+ * 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.validation;
+
+import java.io.IOException ;
+
+import javax.servlet.ServletConfig ;
+import javax.servlet.ServletException ;
+import javax.servlet.ServletOutputStream ;
+import javax.servlet.http.HttpServlet ;
+import javax.servlet.http.HttpServletRequest ;
+import javax.servlet.http.HttpServletResponse ;
+
+import org.apache.jena.fuseki.Fuseki ;
+import org.apache.jena.fuseki.servlets.ServletBase ;
+import org.slf4j.Logger ;
+
+public abstract class ValidatorBase extends HttpServlet
+{
+ protected static Logger serviceLog = Fuseki.requestLog ;
+
+ public static final String cssFile = "/fuseki.css" ;
+ public static final String respService = "X-Service" ;
+
+
+ @Override
+ public void init() throws ServletException
+ { super.init() ; }
+
+ @Override
+ public void init(ServletConfig config) throws ServletException
+ { super.init(config) ; }
+
+ @Override
+ public void destroy()
+ { }
+
+ @Override
+ public void doGet(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ { execute(httpRequest, httpResponse) ; }
+
+ @Override
+ public void doPost(HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ { execute(httpRequest, httpResponse) ; }
+
+ protected abstract void execute(HttpServletRequest httpRequest, HttpServletResponse httpResponse) ;
+
+ protected static void setHeaders(HttpServletResponse httpResponse)
+ {
+ ServletBase.setCommonHeaders(httpResponse) ;
+ httpResponse.setCharacterEncoding("UTF-8") ;
+ httpResponse.setContentType("text/html") ;
+ httpResponse.setHeader(respService, "Fuseki/ARQ SPARQL Query Validator: http://jena.apache.org/") ;
+ }
+
+ protected static String htmlQuote(String str)
+ {
+ StringBuilder sBuff = new StringBuilder() ;
+ for ( int i = 0 ; i < str.length() ; i++ )
+ {
+ char ch = str.charAt(i) ;
+ switch (ch)
+ {
+ case '<': sBuff.append("<") ; break ;
+ case '>': sBuff.append(">") ; break ;
+ case '&': sBuff.append("&") ; break ;
+ default:
+ // Work around Eclipe bug with StringBuffer.append(char)
+ //try { sBuff.append(ch) ; } catch (Exception ex) {}
+ sBuff.append(ch) ;
+ break ;
+ }
+ }
+ return sBuff.toString() ;
+ }
+
+ protected static void startFixed(ServletOutputStream outStream) throws IOException
+ {
+ outStream.println("<pre class=\"box\">") ;
+ }
+
+ protected static void columns(String prefix, ServletOutputStream outStream) throws IOException
+ {
+ outStream.print(prefix) ;
+ outStream.println(" 1 2 3 4 5 6 7") ;
+ outStream.print(prefix) ;
+ outStream.println("12345678901234567890123456789012345678901234567890123456789012345678901234567890") ;
+ }
+
+ protected static void finishFixed(ServletOutputStream outStream) throws IOException
+ {
+ outStream.println("</pre>") ;
+ }
+
+ protected static void printHead(ServletOutputStream outStream, String title) throws IOException
+ {
+ outStream.println("<head>") ;
+ outStream.println(" <title>"+title+"</title>") ;
+ outStream.println(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">") ;
+ outStream.println(" <link rel=\"stylesheet\" type=\"text/css\" href=\""+cssFile+"\" />") ;
+ //outStream.println() ;
+ outStream.println("</head>") ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jena/blob/662cf71d/jena-fuseki1/src/main/resources/META-INF/DEPENDENCIES
----------------------------------------------------------------------
diff --git a/jena-fuseki1/src/main/resources/META-INF/DEPENDENCIES b/jena-fuseki1/src/main/resources/META-INF/DEPENDENCIES
new file mode 100644
index 0000000..910b788
--- /dev/null
+++ b/jena-fuseki1/src/main/resources/META-INF/DEPENDENCIES
@@ -0,0 +1,24 @@
+This file lists the dependences for Apache Jena Fuseki.
+ Version numbers are given in the POM file for a particular distribution.
+
+Apache Projects: Apache Software License
+ Apache Jena, including the Jena IRI library
+ Apache Xerces-J
+ Apache log4j
+ Apache HttpComponents (HTTP Client)
+ Apache Commons Codec
+ Apache Common FileUpload
+
+ICU4J : http://icu-project.org/
+ IBM X License (to version ICU4J 3.4.4)
+
+SLF4J : http://www.slf4j.org/
+ Copyright (c) 2004-2008 QOS.ch
+ MIT License
+
+JUnit : http://junit.org/
+ Common Public License - v 1.0
+
+Jetty: http://www.eclipse.org/jetty/
+ Apache License 2.0
+ (also avilable under Eclipse Public License 1.0)