/* * Copyright Aduna (http://www.aduna-software.com/) (c) 2007. * * Licensed under the Aduna BSD-style license. */ package org.openrdf.query.dawg; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.BINDING; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.RESULTSET; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.RESULTVARIABLE; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.SOLUTION; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.VALUE; import static org.openrdf.query.dawg.DAWGTestResultSetSchema.VARIABLE; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.openrdf.model.Graph; import org.openrdf.model.Literal; import org.openrdf.model.Resource; import org.openrdf.model.Statement; import org.openrdf.model.Value; import org.openrdf.model.impl.GraphImpl; import org.openrdf.model.util.GraphUtil; import org.openrdf.model.util.GraphUtilException; import org.openrdf.model.vocabulary.RDF; import org.openrdf.query.Binding; import org.openrdf.query.TupleQueryResultHandler; import org.openrdf.query.TupleQueryResultHandlerException; import org.openrdf.query.impl.BindingImpl; import org.openrdf.query.impl.MapBindingSet; import org.openrdf.rio.RDFHandlerException; import org.openrdf.rio.helpers.RDFHandlerBase; /** * @author Arjohn Kampman */ public class DAWGTestResultSetParser extends RDFHandlerBase { /*-----------* * Constants * *-----------*/ /** * RDFHandler to report the generated statements to. */ private final TupleQueryResultHandler tqrHandler; /*-----------* * Variables * *-----------*/ private Graph graph = new GraphImpl(); /*--------------* * Constructors * *--------------*/ public DAWGTestResultSetParser(TupleQueryResultHandler tqrHandler) { this.tqrHandler = tqrHandler; } /*---------* * Methods * *---------*/ @Override public void startRDF() throws RDFHandlerException { graph.clear(); } @Override public void handleStatement(Statement st) throws RDFHandlerException { graph.add(st); } @Override public void endRDF() throws RDFHandlerException { try { Resource resultSetNode = GraphUtil.getUniqueSubject(graph, RDF.TYPE, RESULTSET); List<String> bindingNames = getBindingNames(resultSetNode); tqrHandler.startQueryResult(bindingNames); Iterator<Value> solIter = GraphUtil.getObjectIterator(graph, resultSetNode, SOLUTION); while (solIter.hasNext()) { Value solutionNode = solIter.next(); if (solutionNode instanceof Resource) { reportSolution((Resource)solutionNode, bindingNames); } else { new RDFHandlerException("Value for " + SOLUTION + " is not a resource: " + solutionNode); } } tqrHandler.endQueryResult(); } catch (GraphUtilException e) { throw new RDFHandlerException(e.getMessage(), e); } catch (TupleQueryResultHandlerException e) { throw new RDFHandlerException(e.getMessage(), e); } } private List<String> getBindingNames(Resource resultSetNode) throws RDFHandlerException { List<String> bindingNames = new ArrayList<String>(16); Iterator<Value> varIter = GraphUtil.getObjectIterator(graph, resultSetNode, RESULTVARIABLE); while (varIter.hasNext()) { Value varName = varIter.next(); if (varName instanceof Literal) { bindingNames.add(((Literal)varName).getLabel()); } else { throw new RDFHandlerException("Value for " + RESULTVARIABLE + " is not a literal: " + varName); } } return bindingNames; } private void reportSolution(Resource solutionNode, List<String> bindingNames) throws RDFHandlerException, GraphUtilException { MapBindingSet bindingSet = new MapBindingSet(bindingNames.size()); Iterator<Value> bindingIter = GraphUtil.getObjectIterator(graph, solutionNode, BINDING); while (bindingIter.hasNext()) { Value bindingNode = bindingIter.next(); if (bindingNode instanceof Resource) { Binding binding = getBinding((Resource)bindingNode); bindingSet.addBinding(binding); } else { throw new RDFHandlerException("Value for " + BINDING + " is not a resource: " + bindingNode); } } try { tqrHandler.handleSolution(bindingSet); } catch (TupleQueryResultHandlerException e) { throw new RDFHandlerException(e.getMessage(), e); } } private Binding getBinding(Resource bindingNode) throws GraphUtilException { Literal name = GraphUtil.getUniqueObjectLiteral(graph, bindingNode, VARIABLE); Value value = GraphUtil.getUniqueObject(graph, bindingNode, VALUE); return new BindingImpl(name.getLabel(), value); } }