/* * (c) Copyright 2010 Epimorphics Ltd. * All rights reserved. * [See end of file] */ package org.openjena.fuseki.validation; import static org.openjena.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.openjena.atlas.io.IO ; import org.openjena.atlas.lib.Sink ; import org.openjena.atlas.lib.SinkWrapper ; import org.openjena.riot.ErrorHandler ; import org.openjena.riot.Lang ; import org.openjena.riot.RiotException ; import org.openjena.riot.RiotReader ; import org.openjena.riot.lang.LangRIOT ; import org.openjena.riot.system.RiotLib ; import org.openjena.riot.tokens.Tokenizer ; import org.openjena.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 = httpRequest.getParameter(paramSyntax) ; if ( syntax == null || syntax.equals("") ) syntax = Lang.NQUADS.getName() ; Lang language = Lang.get(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("") ; printHead(outStream, "Jena Data Validator Report") ; outStream.println("") ; outStream.println("

RIOT Parser Report

") ; outStream.println("

Line and column numbers refer to original input

") ; outStream.println("

 

") ; 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("") ; outStream.println("") ; } 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 sink = new Sink() { 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) ; } } ; Sink sink2 = new SinkWrapper(sink){ long count = 0 ; @Override public void close() {} @Override public void flush() {} @Override public void send(Quad quad) { super.send(quad) ; count++ ; if ( count > LIMIT ) throw new RiotException("Limit exceeded") ; } } ; // Language? LangRIOT parser = RiotReader.createParserQuads(tokenizer, language, null, sink) ; // 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("
") ; out.print(str) ; out.print("
") ; } catch (IOException ex) { IO.exception(ex) ; } } } private Tokenizer createTokenizer(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws Exception { Reader reader = null ; String[] args = httpRequest.getParameterValues(paramIndirection) ; if ( args == null || args.length == 0 ) { reader = httpRequest.getReader() ; } else if ( args.length > 1 ) { httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Too many parameters for '"+paramIndirection+"='") ; return null ; } // else // { // reader = // get from afar. // } args = httpRequest.getParameterValues(paramData) ; if ( args == null || args.length == 0 ) {} 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) ; } } /* * (c) Copyright 2010 Epimorphics Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */