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.datatypes.TypeMapper;
009 import com.hp.hpl.jena.graph.Node;
010 import com.hp.hpl.jena.graph.Triple;
011 import com.hp.hpl.jena.query.Query;
012 import com.hp.hpl.jena.rdf.model.AnonId;
013 import com.hp.hpl.jena.sparql.core.BasicPattern;
014 import com.hp.hpl.jena.sparql.core.Var;
015 import com.hp.hpl.jena.sparql.syntax.Element;
016 import com.hp.hpl.jena.sparql.syntax.ElementGroup;
017 import com.hp.hpl.jena.sparql.syntax.ElementNamedGraph;
018 import com.hp.hpl.jena.sparql.syntax.Template;
019 import com.hp.hpl.jena.vocabulary.RDF;
020 import java.util.*;
021 import java.util.Map.Entry;
022 import net.rootdev.javardfa.StatementSink;
023 import org.slf4j.Logger;
024 import org.slf4j.LoggerFactory;
025
026 public class QueryCollector implements StatementSink {
027
028 final static Logger log = LoggerFactory.getLogger(QueryCollector.class);
029 private static final Node FormType = Node.createURI("http://www.w3.org/1999/xhtml/vocab/#form");
030 private static final TypeMapper TMapper = TypeMapper.getInstance();
031 private final Map<String, Query> queries;
032 private List<Triple> currentQuery;
033 private String currentQueryName;
034 private final Map<String, String> prefixMapping;
035
036 public QueryCollector() {
037 queries = new HashMap();
038 prefixMapping = new HashMap();
039 }
040
041 public Map<String, Query> getQueries() {
042 return Collections.unmodifiableMap(queries);
043 }
044
045 public void addLiteral(String arg0, String arg1, String arg2, String arg3,
046 String arg4) {
047 //log.info("Add literal");
048 Node subject = getNode(arg0);
049 Node predicate = getNode(arg1);
050 Node object = getLiteralNode(arg2, arg3, arg4);
051 addTriple(subject, predicate, object);
052 }
053
054 public void addObject(String arg0, String arg1, String arg2) {
055 //log.info("Add object");
056 Node subject = getNode(arg0);
057 Node predicate = getNode(arg1);
058 Node object = getNode(arg2);
059 addTriple(subject, predicate, object);
060 }
061
062 private void addTriple(Node subject, Node predicate, Node object) {
063 //log.info("Adding triple: " + subject + " " + predicate + " " + object);
064 if (RDF.type.asNode().equals(predicate) &&
065 FormType.equals(object)) {
066 if (currentQueryName != null) {
067 queries.put(currentQueryName, createQuery(currentQuery));
068 }
069 currentQueryName = subject.getURI();
070 currentQuery = new LinkedList<Triple>();
071 return;
072 }
073 if (currentQueryName == null) {
074 return; // good idea? not sure...
075 }
076 currentQuery.add(Triple.create(subject, predicate, object));
077 }
078
079 private Node getLiteralNode(String arg2, String arg3, String arg4) {
080 if (arg3 == null && arg4 == null) {
081 return Node.createLiteral(arg2);
082 } else if (arg4 == null) { // has lang
083 return Node.createLiteral(arg2, arg3, false);
084 } else { // has datatype
085 return Node.createLiteral(arg2, null, TMapper.getSafeTypeByName(arg4));
086 }
087 }
088
089 private Node getNode(String arg0) {
090 if (arg0.startsWith("_:")) // BNode
091 {
092 return Node.createAnon(AnonId.create(arg0.substring(2)));
093 }
094 if (arg0.startsWith("?")) // Var
095 {
096 return Var.alloc(arg0.substring(1));
097 } else {
098 return Node.createURI(arg0);
099 }
100 }
101
102 public void end() {
103 if (currentQueryName != null) {
104 queries.put(currentQueryName, createQuery(currentQuery));
105 }
106 }
107
108 public void start() {
109 }
110
111 public Query createQuery(List<Triple> triples) {
112 log.info("Create query");
113 Query query = new Query();
114 ElementGroup body = new ElementGroup();
115 for (Triple t : triples) {
116 body.addTriplePattern(t);
117 }
118 // TODO make this switchable.
119 Element pattern = new ElementNamedGraph(Var.alloc("graph"), body);
120 query.setQueryPattern(pattern);
121 query.addProjectVars(Collections.singleton("s"));
122 //query.setQuerySelectType();
123 Template templ = new Template(BasicPattern.wrap(triples));
124 query.setQuerySelectType();
125 query.setQueryResultStar(true);
126 query.setConstructTemplate(templ);
127 for (Entry<String, String> e: prefixMapping.entrySet())
128 query.setPrefix(e.getKey(), e.getValue());
129 return query;
130 }
131
132 public void addPrefix(String prefix, String uri) {
133 prefixMapping.put(prefix, uri);
134 }
135
136 public void setBase(String base) {}
137 }
138
139 /*
140 * (c) Copyright 2009 University of Bristol
141 * All rights reserved.
142 *
143 * Redistribution and use in source and binary forms, with or without
144 * modification, are permitted provided that the following conditions
145 * are met:
146 * 1. Redistributions of source code must retain the above copyright
147 * notice, this list of conditions and the following disclaimer.
148 * 2. Redistributions in binary form must reproduce the above copyright
149 * notice, this list of conditions and the following disclaimer in the
150 * documentation and/or other materials provided with the distribution.
151 * 3. The name of the author may not be used to endorse or promote products
152 * derived from this software without specific prior written permission.
153 *
154 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
155 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
156 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
157 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
158 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
159 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
160 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
161 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
162 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
163 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
164 */