001 /**
002 * Copyright (C) 2007-2011, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program. If not, see <http://www.gnu.org/licenses/>.
018 */
019
020 package org.dllearner.kb.sparql;
021
022 import java.util.ArrayList;
023 import java.util.List;
024 import java.util.Set;
025 import java.util.TreeSet;
026
027 import org.dllearner.utilities.datastructures.StringTuple;
028 import org.dllearner.utilities.owl.OWLVocabulary;
029
030 /**
031 * Can assemble sparql queries. can make queries for subject, predicate, object
032 * according to the filter settings object SparqlQueryType, which gives the
033 * predicate and object lists
034 *
035 * @author Sebastian Hellmann
036 *
037 */
038 public class SparqlQueryMaker {
039
040 private static final String MODE_ALLOW = "allow";
041
042 private static final String MODE_FORBID = "forbid";
043
044 private static final String lineend = "\n";
045
046 // allow false is forbid
047 private boolean allowMode = false;
048
049 private boolean assembled = false;
050
051 private String filter = "";
052
053 private Set<String> objectFilterList;
054
055 private Set<String> predicateFilterList;
056
057 private Set<StringTuple> predicateobjectFilterList;
058
059 private boolean literals = false;
060
061 public void setLiterals(boolean literals) {
062 this.literals = literals;
063 }
064
065 public SparqlQueryMaker(Set<String> objectFilterList,
066 Set<String> predicateFilterList, boolean literals) {
067 super();
068 this.objectFilterList = objectFilterList;
069 this.predicateFilterList = predicateFilterList;
070 this.predicateobjectFilterList = new TreeSet<StringTuple>();
071 this.literals = literals;
072 }
073
074 public SparqlQueryMaker(boolean allowMode,
075 Set<String> objectFilterList,
076 Set<String> predicateFilterList, boolean literals) {
077
078 this(objectFilterList, predicateFilterList, literals);
079 this.allowMode = allowMode;
080 }
081
082 public SparqlQueryMaker(String mode, Set<String> objectFilterList,
083 Set<String> predicateFilterList, boolean literals) {
084 this(objectFilterList, predicateFilterList, literals);
085 if (mode.equalsIgnoreCase(MODE_ALLOW)) {
086 this.allowMode = true;
087 } else if (mode.equalsIgnoreCase(MODE_FORBID)) {
088 this.allowMode = false;
089 } else {
090 this.allowMode = false;
091 }
092 }
093
094 public String makeSubjectQueryUsingFilters(String subject) {
095
096 // String filter = internalFilterAssemblySubject();
097 if (!assembled) {
098 filter = internalFilterAssemblySubject("predicate", "object");
099 filter = (filter.length() > 0) ? "FILTER( " + lineend + filter
100 + "). " : " ";
101 assembled = true;
102 }
103
104 String returnString = "SELECT * WHERE { " + lineend + "<" + subject
105 + "> ?predicate ?object. " + lineend + filter + " } ";
106
107 return returnString;
108 }
109
110 //QUALITY optimize
111 public String makeClassQueryUsingFilters(String subject) {
112
113 // String filter = internalFilterAssemblySubject();
114 String tmpFilter = internalFilterAssemblySubject("predicate", "object");
115 tmpFilter = (tmpFilter.length() > 0) ? "FILTER( " + lineend + tmpFilter
116 + "). " : " ";
117
118 String returnString = "SELECT * WHERE {" +lineend +
119 "<" + subject + "> ?predicate ?object;" +
120 "a ?object . "+lineend+
121 tmpFilter + "}";
122
123 //String returnString = "SELECT * WHERE {" +lineend +
124 // "<" + subject + "> <"+OWLVocabulary.RDF_TYPE+"> ?object. " +lineend+
125 // tmpFilter + "}";
126
127 return returnString;
128 }
129
130 public String makeSubjectQueryLevel(String subject, int level) {
131
132 // String filter = internalFilterAssemblySubject();
133 // if (!assembled) {
134 String filtertmp = "";
135 filtertmp = internalFilterAssemblySubject("predicate0", "object0");
136 filtertmp = (filtertmp.length() > 0) ? "FILTER( " + filtertmp + "). "
137 : " ";
138
139 StringBuffer sbuff = new StringBuffer(1400);
140 sbuff.append("SELECT * WHERE { " + lineend + "{<" + subject
141 + "> ?predicate0 ?object0 ." + lineend);
142 sbuff.append(filtertmp + "} " + lineend);
143
144 // " + lineend + filter +" } ";
145 for (int i = 1; i < level; i++) {
146 sbuff.append("OPTIONAL { ");
147 sbuff.append("?object" + (i - 1) + " ?predicate" + i + " ?object"
148 + i + " . " + lineend);
149
150 filtertmp = internalFilterAssemblySubject("predicate" + i, "object"
151 + i);
152 filtertmp = (filtertmp.length() > 0) ? "FILTER " + filtertmp + ". "
153 : " ";
154
155 sbuff.append(filtertmp + " }");
156 }
157
158 sbuff.append(lineend + "} ");
159
160 return sbuff.toString();
161 }
162
163 private String internalFilterAssemblySubject(String predicateVariable,
164 String objectVariable) {
165 predicateVariable = (predicateVariable.startsWith("?")) ? predicateVariable
166 : "?" + predicateVariable;
167 objectVariable = (objectVariable.startsWith("?")) ? objectVariable
168 : "?" + objectVariable;
169
170 List<String> terms = new ArrayList<String>();
171 String not = (isAllowMode()) ? "" : "!";
172 /*new filter type */
173
174 for (StringTuple tuple : getPredicateObjectFilterList()) {
175 List<String> tmpterms = new ArrayList<String>();
176 tmpterms.add(not + "regex(str(" + predicateVariable + "), '" + tuple.a+ "')");
177 tmpterms.add(not + "regex(str(" + objectVariable + "), '" + tuple.b+ "')");
178 terms.add(assembleTerms(tmpterms, "&&"));
179 }
180
181
182
183 for (String pred : getPredicateFilterList()) {
184 terms.add(not + "regex(str(" + predicateVariable + "), '" + pred
185 + "')");
186 }
187 for (String obj : getObjectFilterList()) {
188 terms
189 .add(not + "regex(str(" + objectVariable + "), '" + obj
190 + "')");
191 }
192 String assembled = assembleTerms(terms, getOperator());
193
194 terms = new ArrayList<String>();
195 // the next line could be removed as it is included in assemble terms
196 if(!assembled.isEmpty()){
197 terms.add(assembled);
198 }
199 if (!isLiterals()) {
200 terms.add("!isLiteral(" + objectVariable + ")");
201 }
202 return assembleTerms(terms, "&&");
203
204
205 }
206
207 private String getOperator(){
208 return (isAllowMode())?"||":"&&";
209
210 }
211
212
213 private String assembleTerms(List<String> terms, String operator) {
214 if((!operator.equals("||")) && (!operator.equals("&&"))){
215 System.out.println("in SparqlQuerymaker assembleTerms recieved wrong operator");
216 System.exit(0);
217 }
218
219 if (terms.isEmpty())
220 return "";
221 else if (terms.size() == 1)
222 return (terms.get(0).isEmpty())?"": brackets(terms.get(0));
223 else {
224 StringBuffer sbuf = new StringBuffer(1400);
225 String first = terms.remove(0);
226 sbuf.append(brackets(first));
227 for (String term : terms) {
228 sbuf.append(lineend + operator);
229 sbuf.append(brackets(term));
230 }
231 return brackets(sbuf.toString());
232 }
233
234 }
235
236 private static String brackets(String s) {
237 return "(" + s + ")";
238 }
239
240 public boolean isLiterals() {
241 return literals;
242 }
243
244 public boolean isAllowMode() {
245 return allowMode;
246 }
247
248 public Set<String> getObjectFilterList() {
249 return objectFilterList;
250 }
251
252 public Set<String> getPredicateFilterList() {
253 return predicateFilterList;
254 }
255 public Set<StringTuple> getPredicateObjectFilterList() {
256 return predicateobjectFilterList;
257 }
258
259 public void addPredicateFilter(String newFilter) {
260 assembled = false;
261 predicateFilterList.add(newFilter);
262 }
263
264 public void addObjectFilter(String newFilter) {
265 assembled = false;
266 objectFilterList.add(newFilter);
267 }
268 public void addPredicateObjectFilter(String pred, String object) {
269 assembled = false;
270 predicateobjectFilterList.add(new StringTuple(pred, object));
271 }
272
273 public void combineWith(SparqlQueryMaker sqm){
274 predicateFilterList.addAll(sqm.predicateFilterList);
275 objectFilterList.addAll(sqm.objectFilterList);
276 }
277
278 public static SparqlQueryMaker getSparqlQueryMakerByName(String name) {
279
280 if (name.equalsIgnoreCase("YAGO"))
281 return getAllowYAGOFilter();
282 else if (name.equalsIgnoreCase("SKOS"))
283 return getAllowSKOSFilter();
284 else if (name.equalsIgnoreCase("YAGOSKOS"))
285 return getAllowYAGOandSKOSFilter();
286 else if (name.equalsIgnoreCase("YAGOSPECIALHIERARCHY"))
287 return getYagoSpecialHierarchyFilter();
288 else if (name.equalsIgnoreCase("YAGOONLY"))
289 return getAllowYAGO_ONLYFilter();
290 else if (name.equalsIgnoreCase("TEST"))
291 return getTestFilter();
292 else if (name.equalsIgnoreCase("DBPEDIA-NAVIGATOR"))
293 return getDBpediaNavigatorFilter();
294 else
295 return null;
296 }
297
298 private void addFiltersForDBpediaSKOS() {
299 addPredicateFilter("http://www.w3.org/2004/02/skos/core");
300 addObjectFilter("http://www.w3.org/2004/02/skos/core");
301 addObjectFilter("http://dbpedia.org/resource/Category:");
302 addObjectFilter("http://dbpedia.org/resource/Template");
303 }
304
305 private void addFiltersForDBpediaUMBEL() {
306 addObjectFilter("http://umbel.org/umbel/");
307 }
308 @SuppressWarnings("unused")
309 private void addFiltersForDBpediaOntology() {
310 addObjectFilter("http://dbpedia.org/ontology/");
311 }
312 @SuppressWarnings("unused")
313 private void addFiltersForDBpediaCyc() {
314 addObjectFilter("http://sw.opencyc.org/2008/06/10/concept/");
315 }
316
317 private void addFiltersForYago() {
318 addObjectFilter("http://dbpedia.org/class/yago");
319
320 }
321
322 private void addFiltersForOWLSameAs() {
323 addPredicateFilter("http://www.w3.org/2002/07/owl#sameAs");
324 }
325 private void addFiltersForFOAF() {
326 addPredicateFilter("http://xmlns.com/foaf/0.1/");
327 addObjectFilter("http://xmlns.com/foaf/0.1/");
328
329 }
330
331 private void addFiltersForWordNet() {
332 addObjectFilter("http://www.w3.org/2006/03/wn/wn20/instances/synset");
333
334 }
335 private void addFiltersForGeonames() {
336 addObjectFilter("http://www.geonames.org");
337
338 }
339 private void addFiltersForFlickrwrappr() {
340 addObjectFilter("http://www4.wiwiss.fu-berlin.de/flickrwrappr");
341
342 }
343
344 private void addFiltersForDBpedia() {
345 addPredicateFilter("http://dbpedia.org/property/reference");
346 addPredicateFilter("http://dbpedia.org/property/website");
347 addPredicateFilter("http://dbpedia.org/property/wikipage");
348 addPredicateFilter("http://dbpedia.org/property/wikiPageUsesTemplate");
349 addPredicateFilter("http://dbpedia.org/property/relatedInstance");
350 addPredicateFilter("http://dbpedia.org/property/owner");
351 addPredicateFilter("http://dbpedia.org/property/standard");
352 addObjectFilter("http://upload.wikimedia.org/wikipedia/commons");
353 addObjectFilter("http://upload.wikimedia.org/wikipedia");
354 }
355
356 public static SparqlQueryMaker getAllowSKOSFilter() {
357 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), false);
358 sqm.combineWith(getAllowYAGOandSKOSFilter());
359 sqm.addFiltersForYago();
360
361 sqm.addPredicateFilter("http://www.w3.org/2004/02/skos/core#narrower");
362 sqm.addObjectFilter("http://dbpedia.org/resource/Template");
363
364 return sqm;
365 }
366
367 public static SparqlQueryMaker getAllowYAGOFilter() {
368 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), false);
369 sqm.combineWith(getAllowYAGOandSKOSFilter());
370 sqm.addFiltersForDBpediaSKOS();
371 return sqm;
372 }
373
374 public static SparqlQueryMaker getAllowYAGO_ONLYFilter() {
375 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), false);
376 sqm.combineWith(getAllowYAGOandSKOSFilter());
377 sqm.addFiltersForDBpediaSKOS();
378 sqm.addFiltersForDBpediaUMBEL();
379 return sqm;
380 }
381
382 public static SparqlQueryMaker getDBpediaNavigatorFilter() {
383 // SparqlQueryMaker sqm = new SparqlQueryMaker("allow", new TreeSet<String>(), new TreeSet<String>(), false);
384 SparqlQueryMaker sqm = new SparqlQueryMaker("allow", new TreeSet<String>(), new TreeSet<String>(), true);
385 // sqm.addPredicateFilter("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
386 // sqm.addPredicateFilter("http://www.w3.org/2000/01/rdf-schema#subClassOf");
387 // sqm.addPredicateFilter("http://www.w3.org/2003/01/geo/wgs84_pos#lat");
388 // sqm.addPredicateFilter("http://www.w3.org/2003/01/geo/wgs84_pos#long");
389 // sqm.addPredicateFilter("http://www.w3.org/2000/01/rdf-schema#label");
390
391 String dbont = "http://dbpedia.org/ontology/";
392 sqm.addPredicateFilter(dbont);
393 sqm.addPredicateFilter(OWLVocabulary.RDFS_range);
394 sqm.addPredicateFilter(OWLVocabulary.RDFS_domain);
395 sqm.addPredicateObjectFilter(dbont, dbont);
396 sqm.addPredicateObjectFilter(OWLVocabulary.RDF_TYPE, dbont);
397 sqm.addPredicateObjectFilter(OWLVocabulary.RDFS_SUBCLASS_OF, dbont);
398 sqm.setLiterals(true);
399
400 // pred.add("http://dbpedia.org/property/wikipage");
401 // pred.add("http://dbpedia.org/property/wikiPageUsesTemplate");
402 // pred.add("http://dbpedia.org/property/relatedInstance");
403 // pred.add("http://dbpedia.org/property/owner");
404 // pred.add("http://dbpedia.org/property/standard");
405 return sqm;
406 }
407
408 public static SparqlQueryMaker getYagoSpecialHierarchyFilter() {
409 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), false);
410 sqm.combineWith(getAllowYAGOFilter());
411 sqm.addPredicateFilter("http://dbpedia.org/property/monarch");
412 return sqm;
413 }
414
415
416
417 public static SparqlQueryMaker getAllowYAGOandSKOSFilter() {
418 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), false);
419 sqm.addFiltersForFOAF();
420 sqm.addFiltersForDBpedia();
421
422 sqm.addFiltersForGeonames();
423 sqm.addFiltersForWordNet();
424 sqm.addFiltersForFlickrwrappr();
425 sqm.addFiltersForOWLSameAs();
426
427 sqm.addPredicateFilter("http://www.w3.org/2004/02/skos/core#narrower");
428 sqm.addObjectFilter("http://dbpedia.org/resource/Template");
429 return sqm;
430 }
431
432 public static SparqlQueryMaker getTestFilter() {
433 SparqlQueryMaker sqm = new SparqlQueryMaker("forbid", new TreeSet<String>(), new TreeSet<String>(), true);
434 sqm.combineWith(getAllowYAGOFilter());
435 return sqm;
436 }
437
438 public static void main(String[] args) {
439
440 String uri = "http://dbpedia.org/resource/Angela_Merkel";
441 // System.out.println(getSparqlQueryMakerByName("YAGO").makeSubjectQueryUsingFilters(uri));
442 // System.out.println(getSparqlQueryMakerByName("YAGO").makeSubjectQueryUsingFilters(uri).length());
443 // System.out.println(getDBpediaNavigatorFilter().makeSubjectQueryUsingFilters(uri));
444 System.out.println();
445 System.out.println(getSparqlQueryMakerByName("YAGO")
446 .makeSubjectQueryLevel(uri, 3));
447
448 }
449
450
451 }