001    /*
002     * (c) Copyright 2009 University of Bristol
003     * All rights reserved.
004     * [See end of file]
005     */
006    package net.rootdev.javardfa;
007    
008    import com.hp.hpl.jena.graph.Node;
009    import com.hp.hpl.jena.graph.Triple;
010    import com.hp.hpl.jena.query.Query;
011    import com.hp.hpl.jena.query.QueryExecution;
012    import com.hp.hpl.jena.query.QueryExecutionFactory;
013    import com.hp.hpl.jena.query.QuerySolution;
014    import com.hp.hpl.jena.query.QuerySolutionMap;
015    import com.hp.hpl.jena.query.ResultSet;
016    import com.hp.hpl.jena.rdf.model.Model;
017    import com.hp.hpl.jena.rdf.model.ModelFactory;
018    import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock;
019    import com.hp.hpl.jena.sparql.syntax.ElementVisitorBase;
020    import com.hp.hpl.jena.sparql.syntax.ElementWalker;
021    import java.io.FileNotFoundException;
022    import java.io.IOException;
023    import java.net.URL;
024    import java.util.LinkedList;
025    import java.util.List;
026    import java.util.Map;
027    import net.rootdev.javardfa.ParserFactory.Format;
028    import org.slf4j.Logger;
029    import org.slf4j.LoggerFactory;
030    import org.xml.sax.SAXException;
031    import org.xml.sax.XMLReader;
032    
033    /**
034     *
035     * Some useful functions concerning pages with variables
036     *
037     * @author pldms
038     */
039    public class QueryUtilities {
040    
041        final static Logger log = LoggerFactory.getLogger(QueryUtilities.class);
042        public final static QuerySolution NoResult = new QuerySolutionMap();
043    
044        /**
045         * Grab simple (BGP) queries from an html document. Over named graphs currently.
046         *
047         * @param format document format
048         * @param source document id
049         * @return
050         */
051        public static Map<String, Query> makeQueries(Format format, String source) throws SAXException, IOException {
052            QueryCollector qc = new QueryCollector();
053            XMLReader reader = ParserFactory.createReaderForFormat(qc, format);
054            ((Parser) reader.getContentHandler()).enable(Setting.FormMode);
055            if (source.matches("file:/[^/][^/].*")) source = source.replaceFirst("file:/", "file:///");
056            reader.parse(source);
057            return qc.getQueries();
058        }
059    
060        // TODO: currently this won't work! Need to add to a named graph
061        /**
062         * Simple method to help rebinding data to form. Currently too simple.
063         * @param model Contains data to rebind
064         * @param query Extracted from the form above
065         * @return Name / node bindings
066         */
067        public static QuerySolution extractBinding(Model model, Query query) {
068            QueryExecution qe = QueryExecutionFactory.create(query, model);
069            ResultSet res = qe.execSelect();
070            final QuerySolution toReturn = (res.hasNext()) ?
071                res.next() : NoResult; // I will never use null again
072            if (res.hasNext()) log.warn("More than one available binding");
073            qe.close();
074            return toReturn;
075        }
076    
077        /**
078         * Given some bindings and a form create a model. Intended use is handling
079         * the result of form submission.
080         *
081         * @param query The form
082         * @param bindings Submitted bindings
083         * @return Bindings applied to the query
084         */
085        public static Model bind(Query query, Map<String, String> bindings) {
086            List<Triple> triples = pullTriples(query);
087            List<Triple> boundTriples = new LinkedList<Triple>();
088            Model model = ModelFactory.createDefaultModel();
089            for (Triple t: triples) {
090                Node s = bind(t.getSubject(), bindings);
091                Node p = bind(t.getPredicate(), bindings);
092                Node o = bind(t.getObject(), bindings);
093                Triple nt = Triple.create(s, p, o);
094                model.add(model.asStatement(nt));
095            }
096            return model;
097        }
098    
099        /**
100         * Collect all triples from a query body
101         * @param query
102         * @return
103         */
104        private static List<Triple> pullTriples(Query query) {
105            List<Triple> triples = new LinkedList<Triple>();
106            ElementWalker.walk(query.getQueryPattern(), new TripleCollector(triples));
107            return triples;
108        }
109    
110        private static Node bind(Node object, Map<String, String> bindings) {
111            throw new UnsupportedOperationException("Not yet implemented");
112        }
113    
114        private static class TripleCollector extends ElementVisitorBase {
115            private final List<Triple> triples;
116    
117            private TripleCollector(List<Triple> triples) {
118                this.triples = triples;
119            }
120    
121            @Override
122            public void visit(ElementTriplesBlock el) {
123                triples.addAll(el.getPattern().getList());
124            }
125    
126        }
127    }
128    
129    /*
130     * (c) Copyright 2009 University of Bristol
131     * All rights reserved.
132     *
133     * Redistribution and use in source and binary forms, with or without
134     * modification, are permitted provided that the following conditions
135     * are met:
136     * 1. Redistributions of source code must retain the above copyright
137     *    notice, this list of conditions and the following disclaimer.
138     * 2. Redistributions in binary form must reproduce the above copyright
139     *    notice, this list of conditions and the following disclaimer in the
140     *    documentation and/or other materials provided with the distribution.
141     * 3. The name of the author may not be used to endorse or promote products
142     *    derived from this software without specific prior written permission.
143     *
144     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
145     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
146     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
147     * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
148     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
149     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
150     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
151     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
152     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
153     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154     */