http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/DataValidator.java new file mode 100644 index 0000000..6105562 --- /dev/null +++ b/jena-fuseki/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/36855e1b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/IRIValidator.java new file mode 100644 index 0000000..2972b49 --- /dev/null +++ b/jena-fuseki/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/36855e1b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/QueryValidator.java new file mode 100644 index 0000000..75ad901 --- /dev/null +++ b/jena-fuseki/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/36855e1b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/UpdateValidator.java new file mode 100644 index 0000000..dd63de8 --- /dev/null +++ b/jena-fuseki/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/36855e1b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java b/jena-fuseki/src/main/java/org/apache/jena/fuseki/validation/ValidatorBase.java new file mode 100644 index 0000000..61820f4 --- /dev/null +++ b/jena-fuseki/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/36855e1b/jena-fuseki/src/main/resources/META-INF/DEPENDENCIES ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/resources/META-INF/DEPENDENCIES b/jena-fuseki/src/main/resources/META-INF/DEPENDENCIES new file mode 100644 index 0000000..910b788 --- /dev/null +++ b/jena-fuseki/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) http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/main/resources/META-INF/LICENSE ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/resources/META-INF/LICENSE b/jena-fuseki/src/main/resources/META-INF/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/jena-fuseki/src/main/resources/META-INF/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/main/resources/META-INF/NOTICE ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/resources/META-INF/NOTICE b/jena-fuseki/src/main/resources/META-INF/NOTICE new file mode 100644 index 0000000..9e0e009 --- /dev/null +++ b/jena-fuseki/src/main/resources/META-INF/NOTICE @@ -0,0 +1,16 @@ +Apache Jena - module Fuseki +Copyright 2011, 2012, 2013, 2014 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +Portions of this software were originally based on the following: + - Copyright 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP + - Copyright 2010, 2011 Epimorphics Ltd. + - Copyright 2010, 2011 Talis Systems Ltd. +These have been licensed to the Apache Software Foundation under a software grant. + +- - - - - - - - - - - - - - - - - - - - - - - + +Portions of this software include software from Mort Bay Consulting Pty. Ltd. + - Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd. http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml b/jena-fuseki/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml new file mode 100644 index 0000000..34082eb --- /dev/null +++ b/jena-fuseki/src/main/resources/org/apache/jena/fuseki/fuseki-properties.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> +<!-- Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0" --> +<properties version="1.0"> + <comment>Fuseki System Properties</comment> + <entry key="org.apache.jena.fuseki.version">${project.version}</entry> + <entry key="org.apache.jena.fuseki.build.datetime">${build.time.xsd}</entry> +</properties> http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/test/java/org/apache/jena/fuseki/ServerTest.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/test/java/org/apache/jena/fuseki/ServerTest.java b/jena-fuseki/src/test/java/org/apache/jena/fuseki/ServerTest.java new file mode 100644 index 0000000..7a4f6dc --- /dev/null +++ b/jena-fuseki/src/test/java/org/apache/jena/fuseki/ServerTest.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.fuseki; + +import 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.rdf.model.Model ; +import com.hp.hpl.jena.rdf.model.ModelFactory ; +import com.hp.hpl.jena.sparql.core.DatasetGraph ; +import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ; +import com.hp.hpl.jena.sparql.modify.request.Target ; +import com.hp.hpl.jena.sparql.modify.request.UpdateDrop ; +import com.hp.hpl.jena.sparql.sse.SSE ; +import com.hp.hpl.jena.update.Update ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateProcessor ; + +/** Manage a server for testing. + * Example for one server per test suite: + * <pre> + \@BeforeClass public static void beforeClass() { ServerTest.allocServer() ; } + \@AfterClass public static void afterClass() { ServerTest.freeServer() ; } + \@Before public void beforeTest() { ServerTest.resetServer() ; } + </pre> + */ +public class ServerTest +{ + // Abstraction that runs a SPARQL server for tests. + + public static final int port = 3535 ; + public static final String urlRoot = "http://localhost:"+port+"/" ; + public static final String datasetPath = "/dataset" ; + public static final String serviceUpdate = "http://localhost:"+port+datasetPath+"/update" ; + public static final String serviceQuery = "http://localhost:"+port+datasetPath+"/query" ; + public static final String serviceREST = "http://localhost:"+port+datasetPath+"/data" ; // ?????? + + public static final String gn1 = "http://graph/1" ; + public static final String gn2 = "http://graph/2" ; + public static final String gn99 = "http://graph/99" ; + + public static final Node n1 = NodeFactory.createURI("http://graph/1") ; + public static final Node n2 = NodeFactory.createURI("http://graph/2") ; + public static final Node n99 = NodeFactory.createURI("http://graph/99") ; + + public static final Graph graph1 = SSE.parseGraph("(base <http://example/> (graph (<x> <p> 1)))") ; + public static final Graph graph2 = SSE.parseGraph("(base <http://example/> (graph (<x> <p> 2)))") ; + + public static final Model model1 = ModelFactory.createModelForGraph(graph1) ; + public static final Model model2 = ModelFactory.createModelForGraph(graph2) ; + + private static EmbeddedFusekiServer server = null ; + + // reference count of start/stop server + private static int countServer = 0 ; + + // This will cause there to be one server over all tests. + // Must be after initialization of counters + //static { allocServer() ; } + + static public void allocServer() + { + if ( countServer == 0 ) + setupServer() ; + countServer++ ; + } + + static public void freeServer() + { + if ( countServer >= 0 ) { + countServer -- ; + if ( countServer == 0 ) + teardownServer() ; + } + } + + protected static void setupServer() + { + DatasetGraph dsg = DatasetGraphFactory.createMem() ; + server = EmbeddedFusekiServer.create(port, dsg, datasetPath) ; + server.start() ; + } + + protected static void teardownServer() { + if ( server != null ) + server.stop() ; + server = null ; + } + public static void resetServer() + { + Update clearRequest = new UpdateDrop(Target.ALL) ; + UpdateProcessor proc = UpdateExecutionFactory.createRemote(clearRequest, ServerTest.serviceUpdate) ; + proc.execute() ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java new file mode 100644 index 0000000..693217f --- /dev/null +++ b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TS_Fuseki.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.fuseki; + +import org.apache.http.client.HttpClient ; +import org.apache.jena.atlas.logging.LogCtl ; +import org.apache.jena.fuseki.http.TestDatasetAccessorHTTP ; +import org.apache.jena.fuseki.http.TestDatasetGraphAccessorHTTP ; +import org.apache.jena.fuseki.http.TestHttpOp ; +import org.apache.jena.riot.web.HttpOp ; +import org.junit.AfterClass ; +import org.junit.BeforeClass ; +import org.junit.runner.RunWith ; +import org.junit.runners.Suite ; + +@RunWith(Suite.class) +@Suite.SuiteClasses( { + TestHttpOp.class + , TestSPARQLProtocol.class + , TestDatasetGraphAccessorHTTP.class + , TestDatasetAccessorHTTP.class + , TestQuery.class + , TestAuth.class +}) +public class TS_Fuseki extends ServerTest +{ + // Use HttpOp caching of connections during testing to stop + // swamping kernel socket management (seems to be most + // acute on Java 1.6) + + static HttpClient defaultHttpClient = HttpOp.getDefaultHttpClient() ; + // Used for all tests except auth tests. + static HttpClient globalCachingClient = HttpOp.createCachingHttpClient() ; + + @BeforeClass public static void beforeClassAbstract1() { + HttpOp.setDefaultHttpClient(globalCachingClient) ; + } + + @AfterClass public static void afterClassAbstract1() { + HttpOp.setDefaultHttpClient(defaultHttpClient) ; + } + + @BeforeClass static public void beforeClass() { LogCtl.disable(Fuseki.requestLogName) ; } + @AfterClass static public void afterClass() { LogCtl.setInfo(Fuseki.requestLogName) ;} +} http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestAuth.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestAuth.java b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestAuth.java new file mode 100644 index 0000000..3324a92 --- /dev/null +++ b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestAuth.java @@ -0,0 +1,420 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.fuseki; + +import java.io.File ; +import java.io.FileWriter ; +import java.io.IOException ; +import java.net.URI ; +import java.net.URISyntaxException ; +import java.util.HashMap ; +import java.util.Map ; + +import org.apache.jena.atlas.logging.LogCtl ; +import org.apache.jena.atlas.web.HttpException ; +import org.apache.jena.atlas.web.auth.PreemptiveBasicAuthenticator ; +import org.apache.jena.atlas.web.auth.ScopedAuthenticator ; +import org.apache.jena.atlas.web.auth.ServiceAuthenticator ; +import org.apache.jena.atlas.web.auth.SimpleAuthenticator ; +import org.apache.jena.fuseki.server.FusekiConfig ; +import org.apache.jena.fuseki.server.SPARQLServer ; +import org.apache.jena.fuseki.server.ServerConfig ; +import org.junit.AfterClass ; +import org.junit.Assert ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.query.ARQ ; +import com.hp.hpl.jena.query.DatasetAccessor ; +import com.hp.hpl.jena.query.DatasetAccessorFactory ; +import com.hp.hpl.jena.query.QueryExecutionFactory ; +import com.hp.hpl.jena.rdf.model.Model ; +import com.hp.hpl.jena.sparql.core.DatasetGraph ; +import com.hp.hpl.jena.sparql.core.DatasetGraphFactory ; +import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP ; +import com.hp.hpl.jena.sparql.engine.http.QueryExceptionHTTP ; +import com.hp.hpl.jena.sparql.engine.http.Service ; +import com.hp.hpl.jena.sparql.modify.UpdateProcessRemoteBase ; +import com.hp.hpl.jena.sparql.util.Context ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateFactory ; +import com.hp.hpl.jena.update.UpdateRequest ; + +/** + * Tests Fuseki operation with authentication enabled + */ +public class TestAuth extends ServerTest { + + private static File realmFile; + private static SPARQLServer server; + + /** + * Sets up the authentication for tests + * @throws IOException + */ + @BeforeClass + public static void setup() throws IOException { + realmFile = File.createTempFile("realm", ".properties"); + + try(FileWriter writer = new FileWriter(realmFile)) { + writer.write("allowed: password, fuseki\n"); + writer.write("forbidden: password, other"); + } + + LogCtl.logLevel(Fuseki.serverLog.getName(), org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + LogCtl.logLevel(Fuseki.requestLog.getName(), org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + LogCtl.logLevel("org.eclipse.jetty", org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); + + DatasetGraph dsg = DatasetGraphFactory.createMem(); + // This must agree with ServerTest + ServerConfig conf = FusekiConfig.defaultConfiguration(datasetPath, dsg, true, true); + conf.port = ServerTest.port; + conf.pagesPort = ServerTest.port; + conf.authConfigFile = realmFile.getAbsolutePath(); + + server = new SPARQLServer(conf); + server.start(); + } + + /** + * Tears down authentication test setup + */ + @AfterClass + public static void teardown() { + server.stop(); + + realmFile.delete(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_01() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + // No auth credentials should result in an error + qe.execAsk(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_02() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + // Auth credentials for valid user with bad password + qe.setBasicAuthentication("allowed", "incorrect".toCharArray()); + qe.execAsk(); + } + + @Test + public void query_with_auth_03() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + // Auth credentials for valid user with correct password + qe.setBasicAuthentication("allowed", "password".toCharArray()); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_04() { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + // Auth credentials for valid user with correct password BUT not in + // correct role + qe.setBasicAuthentication("forbidden", "password".toCharArray()); + qe.execAsk(); + } + + @Test + public void query_with_auth_05() { + // Uses auth and enables compression + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + qe.setAllowDeflate(true); + qe.setAllowGZip(true); + + // Auth credentials for valid user with correct password + qe.setBasicAuthentication("allowed", "password".toCharArray()); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_06() { + // Uses auth and enables compression + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + qe.setAllowDeflate(true); + qe.setAllowGZip(true); + + // Auth credentials for valid user with bad password + qe.setBasicAuthentication("allowed", "incorrect".toCharArray()); + qe.execAsk(); + } + + @Test(expected = QueryExceptionHTTP.class) + public void query_with_auth_07() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password but scoped to + // wrong URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://example"), "allowed", + "password".toCharArray()); + qe.setAuthenticator(authenticator); + qe.execAsk(); + } + + @Test + public void query_with_auth_08() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // correct URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(serviceQuery), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_09() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password using + // pre-emptive auth + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(serviceQuery), "allowed", "password".toCharArray()); + qe.setAuthenticator(new PreemptiveBasicAuthenticator(authenticator)); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_10() { + Context ctx = ARQ.getContext(); + try { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped + // to correct URI + // Provided via Service Context and its associated authenticator + Map<String, Context> serviceContext = new HashMap<String, Context>(); + Context authContext = new Context(); + authContext.put(Service.queryAuthUser, "allowed"); + authContext.put(Service.queryAuthPwd, "password"); + serviceContext.put(serviceQuery, authContext); + ctx.put(Service.serviceContext, serviceContext); + + qe.setAuthenticator(new ServiceAuthenticator()); + Assert.assertTrue(qe.execAsk()); + } finally { + ctx.remove(Service.serviceContext); + } + } + + @Test + public void query_with_auth_11() { + Context ctx = ARQ.getContext(); + try { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped + // to base URI of the actual service URL + // Provided via Service Context and its associated authenticator + Map<String, Context> serviceContext = new HashMap<String, Context>(); + Context authContext = new Context(); + authContext.put(Service.queryAuthUser, "allowed"); + authContext.put(Service.queryAuthPwd, "password"); + serviceContext.put(urlRoot, authContext); + ctx.put(Service.serviceContext, serviceContext); + + qe.setAuthenticator(new ServiceAuthenticator()); + Assert.assertTrue(qe.execAsk()); + } finally { + ctx.remove(Service.serviceContext); + } + } + + @Test + public void query_with_auth_12() { + ARQ.getContext().remove(Service.serviceContext); + + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password + // Use service authenticator with fallback credentials. + qe.setAuthenticator(new ServiceAuthenticator("allowed", "password".toCharArray())); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_13() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // base URI of the actual service URL + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(urlRoot), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test + public void query_with_auth_14() throws URISyntaxException { + QueryEngineHTTP qe = (QueryEngineHTTP) QueryExecutionFactory.sparqlService(serviceQuery, "ASK { }"); + + // Auth credentials for valid user with correct password and scoped to + // base URI of the actual service URL + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://localhost:" + port), "allowed", "password".toCharArray()); + qe.setAuthenticator(authenticator); + Assert.assertTrue(qe.execAsk()); + } + + @Test(expected = HttpException.class) + public void update_with_auth_01() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + // No auth credentials should result in an error + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_02() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + // Auth credentials for valid user with bad password + ue.setAuthentication("allowed", "incorrect".toCharArray()); + ue.execute(); + } + + @Test + public void update_with_auth_03() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + // Auth credentials for valid user with correct password + ue.setAuthentication("allowed", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_04() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + // Auth credentials for valid user with correct password BUT not in + // correct role + ue.setAuthentication("forbidden", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_05() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, serviceUpdate); + // No auth credentials should result in an error + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_06() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, serviceUpdate); + // Auth credentials for valid user with bad password + ue.setAuthentication("allowed", "incorrect".toCharArray()); + ue.execute(); + } + + @Test + public void update_with_auth_07() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, serviceUpdate); + // Auth credentials for valid user with correct password + ue.setAuthentication("allowed", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_08() { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemoteForm(updates, serviceUpdate); + // Auth credentials for valid user with correct password BUT not in + // correct role + ue.setAuthentication("forbidden", "password".toCharArray()); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void update_with_auth_09() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + + // Auth credentials for valid user with correct password but scoped to + // wrong URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI("http://example"), "allowed", + "password".toCharArray()); + ue.setAuthenticator(authenticator); + ue.execute(); + } + + @Test + public void update_with_auth_10() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + + // Auth credentials for valid user with correct password scoped to + // correct URI + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(serviceUpdate), "allowed", "password".toCharArray()); + ue.setAuthenticator(authenticator); + ue.execute(); + } + + @Test + public void update_with_auth_11() throws URISyntaxException { + UpdateRequest updates = UpdateFactory.create("CREATE SILENT GRAPH <http://graph>"); + UpdateProcessRemoteBase ue = (UpdateProcessRemoteBase) UpdateExecutionFactory.createRemote(updates, serviceUpdate); + + // Auth credentials for valid user with correct password scoped to + // correct URI + // Also using pre-emptive auth + ScopedAuthenticator authenticator = new ScopedAuthenticator(new URI(serviceUpdate), "allowed", "password".toCharArray()); + ue.setAuthenticator(new PreemptiveBasicAuthenticator(authenticator)); + ue.execute(); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_01() { + // No auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceREST); + accessor.getModel(); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_02() { + // Incorrect auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceREST, new SimpleAuthenticator("allowed", "incorrect".toCharArray())); + accessor.getModel(); + } + + @Test + public void graphstore_with_auth_03() { + // Correct auth credentials + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceREST, new SimpleAuthenticator("allowed", "password".toCharArray())); + Model m = accessor.getModel(); + Assert.assertTrue(m.isEmpty()); + } + + @Test(expected = HttpException.class) + public void graphstore_with_auth_04() throws URISyntaxException { + // Correct auth credentials scoped to wrong URI + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceREST, new ScopedAuthenticator(new URI("http://example.org/"), "allowed", "password".toCharArray())); + accessor.getModel(); + } + + @Test + public void graphstore_with_auth_05() throws URISyntaxException { + // Correct auth credentials scoped to correct URI + DatasetAccessor accessor = DatasetAccessorFactory.createHTTP(serviceREST, new ScopedAuthenticator(new URI(serviceREST), "allowed", "password".toCharArray())); + accessor.getModel(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestQuery.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestQuery.java b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestQuery.java new file mode 100644 index 0000000..5748dc4 --- /dev/null +++ b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestQuery.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.fuseki; + +import java.io.IOException ; +import java.net.HttpURLConnection ; +import java.net.URL ; + +import static org.apache.jena.fuseki.ServerTest.* ; + +import org.junit.AfterClass ; +import org.junit.Assert ; +import org.junit.BeforeClass ; +import org.junit.Test ; +import org.apache.jena.atlas.junit.BaseTest ; +import com.hp.hpl.jena.query.* ; +import com.hp.hpl.jena.sparql.core.Var ; +import com.hp.hpl.jena.sparql.engine.binding.Binding ; +import com.hp.hpl.jena.sparql.resultset.ResultSetCompare ; +import com.hp.hpl.jena.sparql.sse.Item ; +import com.hp.hpl.jena.sparql.sse.SSE ; +import com.hp.hpl.jena.sparql.sse.builders.BuilderResultSet ; +import com.hp.hpl.jena.sparql.util.Convert ; + +public class TestQuery extends BaseTest +{ + protected static ResultSet rs1 = null ; + static { + Item item = SSE.parseItem("(resultset (?s ?p ?o) (row (?s <x>)(?p <p>)(?o 1)))") ; + rs1 = BuilderResultSet.build(item) ; + } + + // DRY - test protocol? + @BeforeClass public static void beforeClass() + { + ServerTest.allocServer() ; + ServerTest.resetServer() ; + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.putModel(model1) ; + du.putModel(gn1, model2) ; + } + + @AfterClass public static void afterClass() + { + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.deleteDefault() ; + ServerTest.freeServer() ; + } + + @Test public void query_01() + { + execQuery("SELECT * {?s ?p ?o}", 1) ; + } + + @Test public void query_recursive_01() + { + String query = "SELECT * WHERE { SERVICE <" + serviceQuery + "> { ?s ?p ?o . BIND(?o AS ?x) } }"; + try(QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, query)) { + ResultSet rs = qExec.execSelect(); + + Var x = Var.alloc("x"); + while (rs.hasNext()) { + Binding b = rs.nextBinding(); + Assert.assertNotNull(b.get(x)); + } + } + } + + @Test public void query_with_params_01() + { + String query = "ASK { }"; + try(QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery + "?output=json", query)) { + boolean result = qExec.execAsk(); + Assert.assertTrue(result); + } + } + + @Test public void request_id_header_01() throws IOException + { + String qs = Convert.encWWWForm("ASK{}") ; + URL u = new URL(serviceQuery+"?query="+qs); + HttpURLConnection conn = (HttpURLConnection) u.openConnection(); + Assert.assertTrue(conn.getHeaderField("Fuseki-Request-ID") != null); + } + + private void execQuery(String queryString, int exceptedRowCount) + { + QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, queryString) ; + ResultSet rs = qExec.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertEquals(exceptedRowCount, x) ; + } + + private void execQuery(String queryString, ResultSet expectedResultSet) + { + QueryExecution qExec = QueryExecutionFactory.sparqlService(serviceQuery, queryString) ; + ResultSet rs = qExec.execSelect() ; + boolean b = ResultSetCompare.equalsByTerm(rs, expectedResultSet) ; + assertTrue("Result sets different", b) ; + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/36855e1b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java ---------------------------------------------------------------------- diff --git a/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java new file mode 100644 index 0000000..3b86e17 --- /dev/null +++ b/jena-fuseki/src/test/java/org/apache/jena/fuseki/TestSPARQLProtocol.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.jena.fuseki; + +import static org.apache.jena.fuseki.ServerTest.* ; +import org.apache.jena.atlas.junit.BaseTest ; +import org.apache.jena.riot.WebContent ; +import org.junit.AfterClass ; +import org.junit.BeforeClass ; +import org.junit.Test ; + +import com.hp.hpl.jena.query.* ; +import com.hp.hpl.jena.sparql.engine.http.QueryEngineHTTP ; +import com.hp.hpl.jena.sparql.util.Convert ; +import com.hp.hpl.jena.update.UpdateExecutionFactory ; +import com.hp.hpl.jena.update.UpdateFactory ; +import com.hp.hpl.jena.update.UpdateProcessor ; +import com.hp.hpl.jena.update.UpdateRequest ; +// Generally poke the server using Jena APIs +// SPARQL Query +// SPARQL Update +// GSP is done in TestDatasetAccessorHTTP + +public class TestSPARQLProtocol extends BaseTest +{ + @BeforeClass public static void beforeClass() + { + ServerTest.allocServer() ; + ServerTest.resetServer() ; + // Load some data. + DatasetAccessor du = DatasetAccessorFactory.createHTTP(serviceREST) ; + du.putModel(model1) ; + du.putModel(gn1, model2) ; + } + + @AfterClass public static void afterClass() + { + ServerTest.resetServer() ; + ServerTest.freeServer() ; + } + + static String query(String base, String queryString) + { + return base+"?query="+Convert.encWWWForm(queryString) ; + } + + @Test public void query_01() + { + Query query = QueryFactory.create("SELECT * { ?s ?p ?o }") ; + QueryExecution qexec = QueryExecutionFactory.sparqlService(serviceQuery, query) ; + ResultSet rs = qexec.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertTrue( x != 0 ) ; + } + + @Test public void query_02() + { + Query query = QueryFactory.create("SELECT * { ?s ?p ?o }") ; + QueryEngineHTTP engine = QueryExecutionFactory.createServiceRequest(serviceQuery, query) ; + engine.setSelectContentType(WebContent.contentTypeResultsJSON) ; + ResultSet rs = engine.execSelect() ; + int x = ResultSetFormatter.consume(rs) ; + assertTrue( x != 0 ) ; + } + + @Test public void update_01() + { + UpdateRequest update = UpdateFactory.create("INSERT DATA {}") ; + UpdateProcessor proc = UpdateExecutionFactory.createRemote(update, serviceUpdate) ; + proc.execute() ; + } + + @Test public void update_02() + { + UpdateRequest update = UpdateFactory.create("INSERT DATA {}") ; + UpdateProcessor proc = UpdateExecutionFactory.createRemoteForm(update, serviceUpdate) ; + proc.execute() ; + } +}