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