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 */