Package com.hp.hpl.jena.sparql.resultset

Source Code of com.hp.hpl.jena.sparql.resultset.XMLInputStAX$ResultSetStAX

/*
* 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 com.hp.hpl.jena.sparql.resultset;
import java.io.InputStream ;
import java.io.Reader ;
import java.io.StringReader ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.NoSuchElementException ;

import javax.xml.namespace.QName ;
import javax.xml.stream.XMLInputFactory ;
import javax.xml.stream.XMLStreamConstants ;
import javax.xml.stream.XMLStreamException ;
import javax.xml.stream.XMLStreamReader ;

import org.apache.jena.atlas.lib.Closeable ;
import org.apache.jena.atlas.lib.StrUtils ;
import org.apache.jena.atlas.logging.Log ;

import com.hp.hpl.jena.datatypes.RDFDatatype ;
import com.hp.hpl.jena.datatypes.TypeMapper ;
import com.hp.hpl.jena.graph.Node ;
import com.hp.hpl.jena.graph.NodeFactory ;
import com.hp.hpl.jena.query.ARQ ;
import com.hp.hpl.jena.query.QuerySolution ;
import com.hp.hpl.jena.query.ResultSet ;
import com.hp.hpl.jena.rdf.model.AnonId ;
import com.hp.hpl.jena.rdf.model.Model ;
import com.hp.hpl.jena.sparql.ARQConstants ;
import com.hp.hpl.jena.sparql.core.ResultBinding ;
import com.hp.hpl.jena.sparql.core.Var ;
import com.hp.hpl.jena.sparql.engine.binding.Binding ;
import com.hp.hpl.jena.sparql.engine.binding.BindingFactory ;
import com.hp.hpl.jena.sparql.engine.binding.BindingMap ;
import com.hp.hpl.jena.sparql.graph.GraphFactory ;
import com.hp.hpl.jena.sparql.util.LabelToNodeMap ;

/** Code that reads an XML Results format and builds the ARQ structure for the same.
*  Can read result set and boolean result forms.
*  This is a streaming implementation. */


class XMLInputStAX extends SPARQLResult
{
    private static final String XML_NS = ARQConstants.XML_NS ;
   
    public static ResultSet fromXML(InputStream in)
    {
        return fromXML( in, null) ;
    }
   
    public static ResultSet fromXML(InputStream in, Model model)
    {
        XMLInputStAX x =  new XMLInputStAX(in, model) ;
        if ( !x.isResultSet() )
            throw new ResultSetException("Not a result set") ;
        return x.getResultSet() ;
    }

    public static ResultSet fromXML(String str)
    {
        return fromXML(str, null) ;
       
    }
   
    public static ResultSet fromXML(String str, Model model)
    {
        XMLInputStAX x =  new XMLInputStAX(str, model) ;
        if ( !x.isResultSet() )
            throw new ResultSetException("Not a result set") ;
        return x.getResultSet() ;
    }

    public static boolean booleanFromXML(InputStream in)
    {
        XMLInputStAX x =  new XMLInputStAX(in) ;
        return x.getBooleanResult() ;
    }

    public static boolean booleanFromXML(String str)
    {
        XMLInputStAX x =  new XMLInputStAX(str) ;
        return x.getBooleanResult() ;
    }
   
    public XMLInputStAX(InputStream in)
    { this(in, null) ; }

    public XMLInputStAX(InputStream in, Model model)
    {
        XMLInputFactory xf = XMLInputFactory.newInstance() ;
        try
        {
            XMLStreamReader xReader = xf.createXMLStreamReader(in) ;
            worker(xReader, model) ;
        } catch (XMLStreamException e)
        {
            throw new ResultSetException("Can't initialize StAX parsing engine", e) ;
        }
        catch (Exception ex)
        {
            throw new ResultSetException("Failed when initializing the StAX parsing engine", ex) ;
        }
    }

    public XMLInputStAX(String str)
    { this(str, null) ; }
   
    public XMLInputStAX(String str, Model model)
    {
        XMLInputFactory xf = XMLInputFactory.newInstance() ;
        try
        {
            Reader r = new StringReader(str) ;
            XMLStreamReader xReader = xf.createXMLStreamReader(r) ;
            worker(xReader, model) ;
        } catch (XMLStreamException e)
        {
            throw new ResultSetException("Can't initialize StAX parsing engine", e) ;
        }
        catch (Exception ex)
        {
            throw new ResultSetException("Failed when initializing the StAX parsing engine", ex) ;
        }
    }

    private void worker(XMLStreamReader xReader, Model model)
    {
        if ( model == null )
            model = GraphFactory.makeJenaDefaultModel() ;
       
        ResultSetStAX rss = new ResultSetStAX(xReader, model) ;
        if ( rss.isResultSet )
            set(rss) ;
        else
            set(rss.askResult) ;
    }
   
    //private XMLInputStAX()
   
    // -------- Result Set

   
    class ResultSetStAX  implements ResultSet, Closeable
    {
        // ResultSet variables
        QuerySolution current = null ;
        XMLStreamReader parser = null ;
        List<String> variables = new ArrayList<String>() ;
        Binding binding = null ;            // Current binding
        //RefBoolean inputGraphLabels = new RefBoolean(ARQ.inputGraphBNodeLabels, false) ;
        boolean inputGraphLabels = ARQ.isTrue(ARQ.inputGraphBNodeLabels) ;
       
        LabelToNodeMap bNodes = LabelToNodeMap.createBNodeMap() ;
       
        // Type
        boolean isResultSet = false ;

        // Result set
        boolean ordered = false ;
        boolean distinct = false ;
        boolean finished = false ;
        Model model = null ;
        int row = 0 ;
       
        // boolean
        boolean askResult = false ;

        ResultSetStAX(XMLStreamReader reader, Model model)
        {
            parser = reader ;
            this.model = model ;
            init() ;
        }
       
        private void init()
        {       
        try {
            // Because all the tags are different, we could use one big switch statement!
            skipTo(XMLResults.dfHead) ;
            processHead() ;
            skipTo(new String[]{XMLResults.dfResults, XMLResults.dfBoolean}, new String[]{XMLResults.dfResults}) ;
            // Next should be a <result>, <boolean> element or </results>
           
            // Need to decide what sort of thing we are reading.
          
           String tag = parser.getLocalName() ;
           if ( tag.equals(XMLResults.dfResults) )
           {
               isResultSet = true ;
               processResults() ;
           }
           if ( tag.equals(XMLResults.dfBoolean) )
           {
               isResultSet = false ;
               processBoolean() ;
           }
           
        } catch (XMLStreamException ex)
        {
            Log.warn(this ,"XMLStreamException: "+ex.getMessage(), ex) ;
        }
    }
       
    @Override
    public boolean hasNext()
    {
        if ( ! isResultSet )
            throw new ResultSetException("Not an XML result set") ;
       
        if ( finished )
            return false ;
       
        try {
            if ( binding == null )
                binding = getOneSolution() ;
        } catch (XMLStreamException ex)
        {
            staxError("XMLStreamException: "+ex.getMessage(), ex) ;
        }
        boolean b = (binding != null) ;
        //parser.close() ; // Some way to close the input stream.
        if (!b)
            close();
        return b ;
    }

    @Override
    public QuerySolution next()
    {
        return nextSolution() ;
    }

    @Override
    public Binding nextBinding()
    {
        if ( finished )
            throw new NoSuchElementException("End of XML Results") ;
        if ( ! hasNext() )
            throw new NoSuchElementException("End of XML Results") ;
        Binding r = binding ;
        row++ ;
        binding = null ;
        return r ;
    }
   
    @Override
    public QuerySolution nextSolution()
    {
        Binding r = nextBinding() ;
        ResultBinding currentEnv = new ResultBinding(model, r) ;
        return currentEnv ;
    }

    @Override
    public int getRowNumber()
    {
        return row ;
    }

    @Override
    public List<String> getResultVars()
    {
        return variables ;
    }

    public boolean isOrdered() { return ordered ; }
   
    public boolean isDistinct() { return distinct ; }

    // No model - it was from a stream
    @Override
    public Model getResourceModel() { return null ; }

    @Override
    public void remove()
    {
        throw new UnsupportedOperationException(XMLInputStAX.class.getName()) ;
    }
   
    @Override
    public void close()
    { finished = true ; }

    // -------- Boolean stuff
   
    private void processBoolean() throws XMLStreamException
    {
        // At start of <boolean>
        String s = parser.getElementText() ;
        if ( s.equalsIgnoreCase("true") )
        {
            askResult = true ;
            return ;
        }
        if ( s.equalsIgnoreCase("false") )
        {
            askResult = false ;
            return ;
        }
        throw new ResultSetException("Unknown boolean value: "+s) ;
    }
   
    // --------

    private void skipTo(String tag1) throws XMLStreamException
    { skipTo(new String[]{tag1}, null) ; }
   
    private void skipTo(String[] startElementNames, String[] stopElementNames) throws XMLStreamException
    {
        boolean found = false ;
        loop:
            while(parser.hasNext())
            {
                int event = parser.next();
                switch (event)
                {
                    case XMLStreamConstants.END_DOCUMENT:
                        break loop ;
                    case XMLStreamConstants.END_ELEMENT:
                        if ( stopElementNames == null )
                            break ;
                       
                        String endTag = parser.getLocalName() ;
                        if ( endTag != null && containsName(stopElementNames, endTag) )
                            return ;
                        break ;
                    case XMLStreamConstants.START_ELEMENT:
                        if ( startElementNames == null )
                            break ;
                        QName qname = parser.getName() ;
                        if ( ! qname.getNamespaceURI().equals(XMLResults.baseNamespace) )
                            staxError("skipToHead: Unexpected tag: "+qname) ;
                        if ( containsName(startElementNames, qname.getLocalPart()))
                            return ;
                        break ;
                    default:
                        // Skip stuff
                }
            }
       
        if ( ! found )
        {
            String s1 = "" ;
            if ( startElementNames != null )
                s1 = StrUtils.strjoin(", ",startElementNames) ;
           
            String s2 = "" ;
            if ( stopElementNames != null )
                s2 = StrUtils.strjoin(", ",stopElementNames) ;
            Log.warn(this, "Failed to find start and stop of specified elements: "+s1+" :: "+s2) ;
        }
    }
   
    private boolean containsName(String[] elementNames, String eName)
    {
        for ( int i = 0 ; i < elementNames.length ; i++ )
        {
            String s = elementNames[i] ;
            if ( s.equals(eName) )
                return true ;
        }
        return false ;
    }

    private void processHead() throws XMLStreamException
    {
        // Should be at the start of head
       
        loop:
            while(parser.hasNext())
            {
                int event = parser.next();
                String tag = null ;
               
                switch (event)
                {
                    case XMLStreamConstants.END_DOCUMENT:
                        break loop ;
                    case XMLStreamConstants.END_ELEMENT:
                        tag = parser.getLocalName() ;
                        if ( isTag(tag, XMLResults.dfHead ) )
                            break loop ;
                        break ;
                    case XMLStreamConstants.START_ELEMENT:
                        tag = parser.getLocalName() ;
                        if ( isTag(tag, XMLResults.dfHead ) )
                            break ; // This switch statement
                        if ( isTag(tag, XMLResults.dfVariable ) )
                        {
                            String varname = parser.getAttributeValue(null, XMLResults.dfAttrVarName) ;
                            variables.add(varname) ;
                            break ;
                        }
                        if ( isTag(tag, XMLResults.dfLink ) )
                            break ;
                       
                        staxError("Unknown XML element: "+tag) ;
                        break ;
                    default:
                }
            }
    }
   
    // -------- Result Set
   
    private void processResults()
    { return ; }
   
    private Binding getOneSolution() throws XMLStreamException
    {
        // At the start of <result>
        BindingMap binding = BindingFactory.create() ;
        String varName = null ;
       
        while(parser.hasNext())
        {
            int event = parser.next();
            String tag = null ;
           
            switch (event)
            {
                case XMLStreamConstants.END_DOCUMENT:
                    staxError("End of document while processing solution") ;
                    return null ;
                case XMLStreamConstants.END_ELEMENT:
                    tag = parser.getLocalName() ;
                    if ( isTag(tag, XMLResults.dfSolution) )
                        return binding ;
                    if ( isTag(tag, XMLResults.dfResults) )
                        // Hit the end of solutions.
                        return null ;
                    break ;
                case XMLStreamConstants.START_ELEMENT:
                    tag = parser.getLocalName() ;
                    if ( isTag(tag, XMLResults.dfSolution) )
                    {
                        binding = BindingFactory.create() ;
                        break ;
                    }
                    if ( isTag(tag, XMLResults.dfBinding ))
                    {
                        varName = parser.getAttributeValue(null, XMLResults.dfAttrVarName) ;
                        break ;
                    }
                    // URI, literal, bNode, unbound.
                    if ( isTag(tag, XMLResults.dfBNode) )
                    {
                        String label = parser.getElementText() ;
                        Node node = null ;
                        //if ( inputGraphLabels.getValue() )
                        if ( inputGraphLabels )
                            node = NodeFactory.createAnon(new AnonId(label)) ;
                        else
                            node = bNodes.asNode(label) ;
                        addBinding(binding, Var.alloc(varName), node) ;
                        break ;
                    }
                   
                    if ( isTag(tag, XMLResults.dfLiteral) )
                    {
                        String datatype = parser.getAttributeValue(null, XMLResults.dfAttrDatatype) ;

                        //String langTag = parser.getAttributeValue(null, "lang") ;
                       
                        // Woodstox needs XML_NS despite the javadoc of StAX
                        // "If the namespaceURI is null the namespace is not checked for equality"
                        // StAX(.codehaus.org) copes both ways round
                        String langTag = parser.getAttributeValue(XML_NS, "lang") ;
                       
                        // Works for XML literals (returning them as a string)
                        String text = parser.getElementText() ;
                       
                        RDFDatatype dType = null ;
                        if ( datatype != null )
                            dType = TypeMapper.getInstance().getSafeTypeByName(datatype);
                       
                        Node n = NodeFactory.createLiteral(text,  langTag, dType) ;
                        if ( varName == null )
                            throw new ResultSetException("No name for variable") ;
                        addBinding(binding, Var.alloc(varName), n) ;
                        break ;
                    }
                   
                   
                    if ( isTag(tag, XMLResults.dfUnbound) )
                    {
                        break ;
                    }
                    if ( isTag(tag, XMLResults.dfURI) )
                    {
                        String uri = parser.getElementText() ;
                        Node node = NodeFactory.createURI(uri) ;
                        addBinding(binding, Var.alloc(varName), node) ;
                        break ;
                    }
                    break ;
                default:
            }
        }
        staxError("getOneSolution: Hit end unexpectedly") ;
        return null ;
    }
   

    private boolean isTag(String localName, String expectedName)
    {
        if ( ! parser.getNamespaceURI().equals( XMLResults.baseNamespace ))
            return false ;
        return  localName.equals(expectedName) ;
    }

    private void staxError(String msg)
    {
        Log.warn(this, "StAX error: "+msg) ;
        throw new ResultSetException(msg) ;
    }

    private void staxError(String msg, Throwable th)
    {
        Log.warn(this, "StAX error: "+msg, th) ;
        throw new ResultSetException(msg, th) ;
    }
    }
}
TOP

Related Classes of com.hp.hpl.jena.sparql.resultset.XMLInputStAX$ResultSetStAX

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.