001/** 002 * Copyright (C) 2007 - 2016, 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 */ 019package org.dllearner.kb.sparql; 020 021import java.util.List; 022import java.util.Set; 023import java.util.SortedSet; 024import java.util.TreeSet; 025 026import org.apache.log4j.Logger; 027import org.dllearner.reasoning.SPARQLReasoner; 028import org.dllearner.utilities.datastructures.RDFNodeTuple; 029import org.dllearner.utilities.datastructures.StringTuple; 030import org.dllearner.utilities.owl.OWLClassExpressionToSPARQLConverter; 031import org.dllearner.utilities.owl.OWLVocabulary; 032import org.semanticweb.owlapi.model.IRI; 033import org.semanticweb.owlapi.model.OWLClass; 034import org.semanticweb.owlapi.model.OWLDataFactory; 035import org.semanticweb.owlapi.model.OWLDataProperty; 036import org.semanticweb.owlapi.model.OWLEntity; 037import org.semanticweb.owlapi.model.OWLObjectProperty; 038import org.semanticweb.owlapi.vocab.OWLRDFVocabulary; 039 040import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; 041import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; 042 043import org.apache.jena.query.Query; 044import org.apache.jena.query.QuerySolution; 045import org.apache.jena.query.ResultSet; 046import org.apache.jena.query.ResultSetFactory; 047import org.apache.jena.query.ResultSetFormatter; 048import org.apache.jena.query.ResultSetRewindable; 049 050/** 051 * Convenience class for SPARQL queries initialized 052 * with a SparqlEndpoint. A Cache can also be used to further improve 053 * query time. Some methods allow basic reasoning 054 * 055 * @author Sebastian Hellmann 056 * @author Jens Lehmann 057 */ 058public class SPARQLTasks { 059 060 private static Logger logger = Logger.getLogger(SPARQLTasks.class); 061 062 private final Cache cache; 063 064 private final SparqlEndpoint sparqlEndpoint; 065 066 OWLDataFactory df = new OWLDataFactoryImpl(); 067 SPARQLReasoner reasoner; 068 069 /** 070 * @param sparqlEndpoint 071 * the Endpoint the sparql queries will be send to 072 */ 073 public SPARQLTasks(final SparqlEndpoint sparqlEndpoint) { 074 this(null, sparqlEndpoint); 075 } 076 077 /** 078 * @param cache 079 * a cache object 080 * @param sparqlEndpoint 081 * the Endpoint the sparql queries will be send to 082 */ 083 public SPARQLTasks(final Cache cache, final SparqlEndpoint sparqlEndpoint) { 084 this.cache = cache; 085 this.sparqlEndpoint = sparqlEndpoint; 086 087 reasoner = new SPARQLReasoner(sparqlEndpoint); 088 } 089 090 /** 091 * get all superclasses up to a certain depth, 1 means direct superclasses 092 * only. 093 * 094 * @param classURI 095 * the uri of the class with no quotes for which the superclasses 096 * will be retrieved 097 * @param maxDepth 098 * how far the RDF graph will be explored (1 means only direct 099 * SuperClasses) 100 * @return a Sorted String Set of all ClassNames, including the starting 101 * class 102 */ 103 public SortedSet<String> getSuperClasses(final String classURI, 104 final int maxDepth) { 105 // TODO check for quotes in uris 106 return getRecursiveSuperOrSubClasses(classURI, maxDepth, false); 107 } 108 109 public SortedSet<String> getParallelClasses(String classURI, int limit) { 110 String query = "SELECT ?sub WHERE { <" + classURI + "> <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?super ."; 111 query += "?sub <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?super ."; 112 query += "FILTER( ?sub != <" + classURI + ">) . } LIMIT " + limit; 113 return queryAsSet(query, "?sub"); 114// SparqlQuery sq = new SparqlQuery(query, sparqlEndpoint); 115// ResultSet rs = sq.send(); 116 117 } 118 119 /** 120 * This is the underlying function to get Super and SubClasses. 121 * 122 * @param classURI 123 * the uri of the class with no quotes for which the classes will 124 * be retrieved 125 * @param maxDepth 126 * how far the RDF graph will be explored (1 means only direct 127 * related Classes) 128 * @return a Sorted String Set of all retrieved ClassNames, including the 129 * starting class 130 */ 131 private SortedSet<String> getRecursiveSuperOrSubClasses( 132 final String classURI, final int maxDepth, boolean subclasses) { 133 // TODO check for quotes in uris 134 int depth = maxDepth; 135 136 final SortedSet<String> toBeRetrieved = new TreeSet<>(); 137 toBeRetrieved.add(classURI); 138 139 final SortedSet<String> returnSet = new TreeSet<>(); 140 final SortedSet<String> tmpSet = new TreeSet<>(); 141 142 // collect super/subclasses for the depth 143 for (; (depth > 0) && (!toBeRetrieved.isEmpty()); depth--) { 144 // collect super/subclasses for each class in toBeRetrieved 145 // accumulate in tmpSet 146 for (String oneClass : toBeRetrieved) { 147 if (subclasses) { 148 tmpSet.addAll(getDirectSubClasses(oneClass)); 149 } else { 150 tmpSet.addAll(getDirectSuperClasses(oneClass)); 151 } 152 153 }// end inner for 154 155 // remember all queried classes to return them. 156 returnSet.addAll(toBeRetrieved); 157 // then discard them 158 toBeRetrieved.clear(); 159 // all that are to be retrieved the next time. 160 toBeRetrieved.addAll(tmpSet); 161 // small optimization, remove all that have been processed already: 162 toBeRetrieved.removeAll(returnSet); 163 // reset 164 tmpSet.clear(); 165 }// end outer for 166 167 returnSet.addAll(toBeRetrieved); 168 169 return returnSet; 170 } 171 172 /** 173 * gets a SortedSet of all subclasses up to a certain depth 174 * 175 * TODO the mentioned method does not exist 176 * conceptRewrite(String descriptionKBSyntax, SparqlEndpoint se, Cache 177 * c, boolean simple ) 178 * @param classURI An URI string with no quotes 179 * @param maxDepth determines the depth of retrieval, if only direct subclasses are retrieved, 180 * 1 is HIGHLY RECOMMENDED FOR LARGE HIERARCHIES) 181 * @return TreeSet of subclasses including classURI 182 */ 183 public SortedSet<String> getSubClasses(final String classURI, 184 final int maxDepth) { 185// TODO check for quotes in uris 186 return getRecursiveSuperOrSubClasses(classURI, maxDepth, true); 187 } 188 189 /** 190 * returns all direct subclasses of String concept 191 * 192 * @param concept 193 * An URI string with no quotes 194 * @return SortedSet of direct subclasses as String 195 */ 196 private SortedSet<String> getDirectSubClasses(String concept) { 197 return queryPatternAsSet("?subject", "<" + OWLVocabulary.RDFS_SUBCLASS_OF + ">", "<" 198 + concept + ">", "subject", 0, false); 199 } 200 201 private SortedSet<String> getDirectSuperClasses(String concept) { 202 return queryPatternAsSet("<" + concept + ">", "<" + OWLVocabulary.RDFS_SUBCLASS_OF + ">", 203 "?object", "object", 0, false); 204 } 205 206 /** 207 * Retrieves all resource for a fixed role and object. These instances are 208 * distinct. QUALITY: buggy because role doesn't work sometimes get subject 209 * with fixed role and object 210 * 211 * @param role 212 * An URI string with no quotes 213 * @param object 214 * An URI string with no quotes 215 * @param sparqlResultLimit 216 * Limits the ResultSet size 217 * @return SortedSet with the resulting subjects 218 */ 219 public SortedSet<String> retrieveDISTINCTSubjectsForRoleAndObject( 220 String role, String object, int sparqlResultLimit) { 221 return queryPatternAsSet("?subject", "<" + role + ">", "<" + object 222 + ">", "subject", sparqlResultLimit, true); 223 } 224 225 /** 226 * @param subject 227 * An URI string with no quotes 228 * @param role 229 * An URI string with no quotes 230 * @param sparqlResultLimit 231 * Limits the ResultSet size 232 * @return SortedSet with the resulting objects 233 */ 234 public SortedSet<String> retrieveObjectsForSubjectAndRole(String subject, 235 String role, int sparqlResultLimit) { 236 return queryPatternAsSet("<" + subject + ">", "<" + role + ">", 237 "?object", "object", sparqlResultLimit, true); 238 } 239 240 /** 241 * all instances for a SKOS concept. 242 * 243 * @param skosConcept 244 * An URI string with no quotes 245 * @param sparqlResultLimit 246 * Limits the ResultSet size 247 * @return SortedSet with the instances 248 */ 249 public SortedSet<String> retrieveInstancesForSKOSConcept( 250 String skosConcept, int sparqlResultLimit) { 251 return queryPatternAsSet("?subject", "?predicate", "<" + skosConcept 252 + ">", "subject", sparqlResultLimit, false); 253 } 254 255 /** 256 * get all direct Classes of an instance. 257 * 258 * @param instance 259 * An URI string with no quotes 260 * @param sparqlResultLimit 261 * Limits the ResultSet size 262 */ 263 public SortedSet<String> getClassesForInstance(String instance, 264 int sparqlResultLimit) { 265 266 // String sparqlQueryString = "SELECT ?subject WHERE { \n " + "<" + 267 // instance 268 // + ">" + " a " + "?subject " + "\n" + "} " + limit(sparqlResultLimit); 269 return queryPatternAsSet("<" + instance + ">", "a", "?object", 270 "object", sparqlResultLimit, false); 271 // return queryAsSet(sparqlQueryString, "subject"); 272 } 273 274 /** 275 * Returns all instances that are in the prefield (subject) of the 276 * property/role. 277 * 278 * Cave: These have to fulfill the following requirements: 1. They are not 279 * literals 2. They have at least a Class assigned 3. DISTINCT is used in 280 * the query 281 * 282 * TODO there might be a better name for the function 283 * 284 * @param role 285 * An URI of a property/role 286 * @param sparqlResultLimit 287 * ResultSet limit 288 * @return A String Set of instances 289 */ 290 public SortedSet<String> getDomainInstances(String role, 291 int sparqlResultLimit) { 292 293 String sparqlQueryString = "SELECT DISTINCT ?domain " + "WHERE { \n" 294 + "?domain <" + role + "> " + " ?o. \n" + "?domain a []\n." 295 + "FILTER (!isLiteral(?domain))." + "}\n" 296 + limit(sparqlResultLimit); 297 298 return queryAsSet(sparqlQueryString, "domain"); 299 300 } 301 302 /** 303 * Returns all instances that are fillers of the property/role. Cave: These 304 * have to fulfill the following requirements: 1. The fillers are not 305 * literals 2. The fillers have at least a Class assigned 3. DISTINCT is 306 * used in the query 307 * 308 * TODO there might be a better name for the function 309 * 310 * @param role 311 * An URI of a property/role 312 * @param sparqlResultLimit 313 * ResultSet limit 314 * @return A String Set of instances 315 */ 316 public SortedSet<String> getRangeInstances(String role, 317 int sparqlResultLimit) { 318 319 String sparqlQueryString = "SELECT DISTINCT ?range " + "WHERE { \n" 320 + "?s <" + role + "> " + " ?range. \n" + "?range a [].\n" 321 + "FILTER (!isLiteral(?range))." + "}\n" 322 + limit(sparqlResultLimit); 323 324 return queryAsSet(sparqlQueryString, "range"); 325 326 } 327 328 /** 329 * query a pattern with a standard SPARQL query. The Query will be of the 330 * form SELECT * WHERE { subject predicate object } LIMIT X. It has a high 331 * degree of freedom, but only one variabla can be retrieved. 332 * 333 * usage example 1 : queryPatternAsSet( "?subject", "<http://somerole>", 334 * "?object", "subject" ). retrieves all subjects, that have the role, 335 * somerole 336 * 337 * usage example 1 : queryPatternAsSet( "?subject", "<http://somerole>", 338 * "?object", "object" ). retrieves all objects, that have the role, 339 * somerole 340 * 341 * @param subject 342 * An URI string enclosed in <> or a SPARQL variable e.g. 343 * "?subject" 344 * @param predicate 345 * An URI string enclosed in <> or a SPARQL variable e.g. 346 * "?predicate" 347 * @param object 348 * An URI string enclosed in <> or a SPARQL variable e.g. 349 * "?object" 350 * @param variable 351 * The variable to be retrieved and put into the SortedSet 352 * @param sparqlResultLimit 353 * 0 means all 354 * @param distinct 355 * determines whether distinct is used 356 * @return a String Set with the Bindings of the variable in variable 357 */ 358 public SortedSet<String> queryPatternAsSet(String subject, 359 String predicate, String object, String variable, 360 int sparqlResultLimit, boolean distinct) { 361 String sparqlQueryString = "SELECT " + ((distinct) ? "DISTINCT" : "") 362 + " * WHERE { \n " + " " + subject + " " + predicate + " " 363 + object + " \n" + "} " + limit(sparqlResultLimit); 364 return queryAsSet(sparqlQueryString, variable); 365 } 366 367 @Deprecated 368 public SortedSet<StringTuple> queryAsTuple(String subject, boolean filterLiterals) { 369 ResultSetRewindable rs = null; 370 String p = "predicate"; 371 String o = "object"; 372 String lits = (filterLiterals)? ".FILTER (!isLiteral(?"+o+"))." : ""; 373 String sparqlQueryString = "SELECT * WHERE { <"+subject+"> ?"+p+" ?"+o+" "+lits+" } "; 374 375 try { 376 String jsonString = query(sparqlQueryString); 377 rs = SparqlQuery.convertJSONtoResultSet(jsonString); 378 379 } catch (Exception e) { 380 logger.warn(e.getMessage()); 381 } 382 383 //SimpleClock sc = new SimpleClock(); 384 //rw = ResultSetFactory.makeRewindable(rs); 385 //sc.printAndSet("rewindable"); 386 return getTuplesFromResultSet(rs, p, o); 387 } 388 389 @Deprecated 390 public SortedSet<StringTuple> queryAsTuple(String sparqlQueryString, String var1, String var2) { 391 ResultSetRewindable rs = null; 392 try { 393 String jsonString = query(sparqlQueryString); 394 rs = SparqlQuery.convertJSONtoResultSet(jsonString); 395 396 } catch (Exception e) { 397 logger.warn(e.getMessage()); 398 } 399 400 //SimpleClock sc = new SimpleClock(); 401 //rw = ResultSetFactory.makeRewindable(rs); 402 //sc.printAndSet("rewindable"); 403 return getTuplesFromResultSet(rs, var1, var2); 404 } 405 406 @SuppressWarnings("unchecked") 407 public SortedSet<RDFNodeTuple> queryAsRDFNodeTuple(String sparqlQueryString, String var1, String var2) { 408 ResultSetRewindable rsw = null; 409 SortedSet<RDFNodeTuple> returnSet = new TreeSet<>(); 410 411 try { 412 String jsonString = query(sparqlQueryString); 413 rsw = SparqlQuery.convertJSONtoResultSet(jsonString); 414 415 416 417 List<QuerySolution> l = ResultSetFormatter.toList(rsw); 418 for (QuerySolution resultBinding : l) { 419 returnSet.add(new RDFNodeTuple(resultBinding.get(var1),resultBinding.get(var2))); 420 } 421 422 rsw.reset(); 423 } catch (Exception e) { 424 logger.info("ignoring (see log for details): Exception caught in SPARQLTasks, passing empty result: "+e.getMessage()); 425 } 426 427 return returnSet; 428 } 429 430 431 /** 432 * little higher level, executes query ,returns all resources for a 433 * variable. 434 * 435 * @param sparqlQueryString 436 * The query 437 * @param variable 438 * The single variable used in the query 439 */ 440 public SortedSet<String> queryAsSet(String sparqlQueryString, 441 String variable) { 442 ResultSet rs = null; 443 try { 444 String jsonString = query(sparqlQueryString); 445 rs = SparqlQuery.convertJSONtoResultSet(jsonString); 446 447 } catch (Exception e) { 448 logger.warn(e.getMessage()); 449 } 450 return getStringSetForVariableFromResultSet(ResultSetFactory 451 .makeRewindable(rs), variable); 452 } 453 454 /** 455 * low level, executes query returns ResultSet. 456 * 457 * @param sparqlQueryString 458 * The query 459 * @return jena ResultSet 460 */ 461 public ResultSetRewindable queryAsResultSet(String sparqlQueryString) { 462 SparqlQuery sq = new SparqlQuery(sparqlQueryString, sparqlEndpoint); 463 if(cache == null) { 464 return sq.send(); 465 } else { 466 // get JSON from cache and convert to result set 467 String json = cache.executeSparqlQuery(sq); 468 return SparqlQuery.convertJSONtoResultSet(json); 469 } 470 } 471 472 /** 473 * variable must be ?count 474 * @param sparqlQueryString the SPARQL query 475 * @return -1 on failure count on success 476 */ 477 public int queryAsCount(String sparqlQueryString) { 478 SparqlQuery sq = new SparqlQuery(sparqlQueryString, sparqlEndpoint); 479 ResultSetRewindable rsw = null; 480 if(cache == null) { 481 rsw = sq.send(); 482 } else { 483 // get JSON from cache and convert to result set 484 String json = cache.executeSparqlQuery(sq); 485 rsw = SparqlQuery.convertJSONtoResultSet(json); 486 } 487 int ret = -1; 488 while(rsw.hasNext()){ 489 QuerySolution qs = rsw.nextSolution(); 490 ret = qs.getLiteral("count").getInt(); 491 492 } 493 return ret; 494 495 } 496 497 /** 498 * low level, executes query returns JSON. 499 * 500 * @param sparqlQueryString 501 * The query 502 */ 503 public String query(String sparqlQueryString) { 504 String jsonString; 505 if (cache == null) { 506 507 SparqlQuery sq = new SparqlQuery(sparqlQueryString, sparqlEndpoint); 508 //SimpleClock sc = new SimpleClock(); 509 sq.send(false); 510 //sc.printAndSet("querysend"); 511 jsonString = sq.getJson(); 512 513 } else { 514 jsonString = cache.executeSparqlQuery(new SparqlQuery( 515 sparqlQueryString, sparqlEndpoint)); 516 } 517 return jsonString; 518 } 519 520 public boolean ask(String askQueryString) { 521 if(cache == null) { 522 SparqlQuery sq = new SparqlQuery(askQueryString, sparqlEndpoint); 523 return sq.sendAsk(); 524 } else { 525 return cache.executeSparqlAskQuery(new SparqlQuery(askQueryString, sparqlEndpoint)); 526 } 527 } 528 529 /** 530 * a String Helper which constructs the limit clause of a sparql query. if 531 * sparqlResultLimit is zero, returns nothing 532 * 533 * @param sparqlResultLimit 534 * the resultsetlimit 535 * @return LIMIT sparqlResultLimit if bigger than zero, else returns ""; 536 */ 537 private String limit(int sparqlResultLimit) { 538 return (sparqlResultLimit > 0) ? (" LIMIT " + sparqlResultLimit) : ""; 539 } 540 541 public static SortedSet<String> getStringSetForVariableFromResultSet( 542 ResultSetRewindable rs, String variable) { 543 final SortedSet<String> result = new TreeSet<>(); 544 545 @SuppressWarnings("unchecked") 546 final List<QuerySolution> l = ResultSetFormatter.toList(rs); 547 548 for (QuerySolution resultBinding : l) { 549 result.add(resultBinding.get(variable).toString()); 550 } 551 rs.reset(); 552 return result; 553 554 } 555 556 private static SortedSet<StringTuple> getTuplesFromResultSet( 557 ResultSetRewindable rs, String predicate, String object) { 558 final SortedSet<StringTuple> returnSet = new TreeSet<>(); 559 //SimpleClock sc = new SimpleClock(); 560 @SuppressWarnings("unchecked") 561 final List<QuerySolution> l = ResultSetFormatter.toList(rs); 562 for (QuerySolution resultBinding : l) { 563 returnSet.add(new StringTuple(resultBinding.get(predicate).toString(),resultBinding.get(object).toString())); 564 } 565 //sc.printAndSet("allTuples"); 566 rs.reset(); 567 //sc.printAndSet("reset"); 568 return returnSet; 569 570 } 571 572 /** 573 * get all instances for a complex concept / class description in KBSyntax. 574 * 575 * @param conceptKBSyntax 576 * A description string in KBSyntax 577 * @param sparqlResultLimit 578 * Limits the ResultSet size 579 * @return SortedSet with the instance uris 580 */ 581 public SortedSet<String> retrieveInstancesForClassDescription( 582 String conceptKBSyntax, int sparqlResultLimit) { 583 OWLClassExpressionToSPARQLConverter conv = new OWLClassExpressionToSPARQLConverter(); 584 String rootVariable = "subject"; 585 String sparqlQueryString = ""; 586 try { 587 Query query = conv.asQuery(rootVariable, new OWLClassImpl(IRI.create(conceptKBSyntax))); 588 query.setLimit(sparqlResultLimit); 589 sparqlQueryString = query.toString(); 590 } catch (Exception e) { 591 logger.warn(e.getMessage()); 592 } 593 return queryAsSet(sparqlQueryString, rootVariable); 594 } 595 596 public SparqlEndpoint getSparqlEndpoint() { 597 return sparqlEndpoint; 598 } 599 600 public static SPARQLTasks getPredefinedSPARQLTasksWithCache(String endpointName) { 601 return new SPARQLTasks( Cache.getDefaultCache(), SparqlEndpoint.getEndpointByName(endpointName) ); 602 } 603 604 // tries to detect the type of the resource 605 public OWLEntity guessResourceType(String resource) { 606 SortedSet<String> types = retrieveObjectsForSubjectAndRole(resource, 607 OWLRDFVocabulary.RDF_TYPE.getIRI().toString(), 10000); 608// System.out.println(types); 609 if(types.contains(OWLRDFVocabulary.OWL_OBJECT_PROPERTY.getIRI().toString())) { 610 return df.getOWLObjectProperty(IRI.create(resource)); 611 } else if(types.contains(OWLRDFVocabulary.OWL_DATA_PROPERTY.getIRI().toString())) { 612 return df.getOWLDataProperty(IRI.create(resource)); 613 } else if(types.contains(OWLRDFVocabulary.OWL_CLASS.getIRI().toString())) { 614 return df.getOWLClass(IRI.create(resource)); 615 } else { 616 return null; 617 } 618 } 619 620 // tries to detect the type of the resource 621 public OWLEntity guessResourceType(String resource, boolean byTriples) { 622 SortedSet<String> types = retrieveObjectsForSubjectAndRole(resource, "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 10000); 623// System.out.println(types); 624 if(types.contains(OWLRDFVocabulary.OWL_OBJECT_PROPERTY.getIRI().toString())) { 625 return df.getOWLObjectProperty(IRI.create(resource)); 626 } else if(types.contains(OWLRDFVocabulary.OWL_DATA_PROPERTY.getIRI().toString())) { 627 return df.getOWLDataProperty(IRI.create(resource)); 628 } else if(types.contains(OWLRDFVocabulary.OWL_CLASS.getIRI().toString())) { 629 return df.getOWLClass(IRI.create(resource)); 630 } else { 631 if(byTriples){ 632 String queryString = String.format("ASK {?s a <%s>}", resource); 633 SparqlQuery sq = new SparqlQuery(queryString, sparqlEndpoint); 634 boolean isClass = sq.sendAsk(); 635 if(isClass){ 636 return df.getOWLClass(IRI.create(resource)); 637 } else { 638 queryString = String.format("SELECT ?o WHERE {?s <%s> ?o.} LIMIT 10", resource); 639 sq = new SparqlQuery(queryString, sparqlEndpoint); 640 ResultSet rs = sq.send(false); 641 QuerySolution qs = null; 642 boolean isDataProperty = false; 643 boolean isObjectProperty = false; 644 while(rs.hasNext()){ 645 qs = rs.next(); 646 if(qs.get("o").isLiteral()){ 647 isDataProperty = true; 648 } else if(qs.get("o").isResource()){ 649 isObjectProperty = true; 650 } 651 652 } 653 if(isDataProperty && !isObjectProperty){ 654 return df.getOWLDataProperty(IRI.create(resource)); 655 } else if(!isDataProperty && isObjectProperty){ 656 return df.getOWLObjectProperty(IRI.create(resource)); 657 } 658 } 659 } 660 661 return null; 662 } 663 } 664 665 public Set<OWLObjectProperty> getAllObjectProperties() { 666 Set<OWLObjectProperty> properties = new TreeSet<>(); 667 String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#> SELECT ?p WHERE {?p a owl:ObjectProperty}"; 668 SparqlQuery sq = new SparqlQuery(query, sparqlEndpoint); 669 ResultSet q = sq.send(false); 670 while (q.hasNext()) { 671 QuerySolution qs = q.next(); 672 properties.add(df.getOWLObjectProperty(IRI.create(qs.getResource("p").getURI()))); 673 } 674 return properties; 675 } 676 677 public Set<OWLDataProperty> getAllDataProperties() { 678 Set<OWLDataProperty> properties = new TreeSet<>(); 679 String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#> SELECT ?p WHERE {?p a owl:DatatypeProperty}"; 680 SparqlQuery sq = new SparqlQuery(query, sparqlEndpoint); 681 ResultSet q = sq.send(false); 682 while (q.hasNext()) { 683 QuerySolution qs = q.next(); 684 properties.add(df.getOWLDataProperty(IRI.create(qs.getResource("p").getURI()))); 685 } 686 return properties; 687 } 688 689 public Set<OWLClass> getAllClasses() { 690 Set<OWLClass> classes = new TreeSet<>(); 691 String query = "SELECT ?c WHERE {?c a <http://www.w3.org/2002/07/owl#Class>} LIMIT 1000"; 692 /* 693 * String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> " + 694 "SELECT ?c WHERE {{?c a owl:Class} UNION {?c rdfs:subClassOf ?d} UNION {?d rdfs:subClassOf ?c}} LIMIT 1000"; 695 */ 696 SparqlQuery sq = new SparqlQuery(query, sparqlEndpoint); 697 ResultSet q = sq.send(false); 698 while (q.hasNext()) { 699 QuerySolution qs = q.next(); 700 if(qs.getResource("c").isURIResource()){ 701 classes.add(df.getOWLClass(IRI.create(qs.getResource("c").getURI()))); 702 } 703 704 } 705 //remove trivial classes 706 classes.remove(df.getOWLThing()); 707 classes.remove(df.getOWLNothing()); 708 return classes; 709 } 710 711 public boolean supportsSPARQL_1_1(){ 712 String query = "SELECT * WHERE {?s a ?o. {SELECT * WHERE {?s a ?o.} LIMIT 1} } LIMIT 1"; 713 SparqlQuery sq = new SparqlQuery(query, sparqlEndpoint); 714 try { 715 sq.send(false); 716 return true; 717 } catch (Exception e) { 718 System.out.println("Endpoint doesn't seem to support SPARQL 1.1 ."); 719 } 720 return false; 721 } 722 723 724 725} 726 727/* 728 * here are some old functions, which were workarounds: 729 * 730 * 731 * workaround for a sparql glitch {?a owl:subclassOf ?b} returns an 732 * empty set on some endpoints. returns all direct subclasses of String concept 733 * 734 * @param concept An URI string with no quotes @return SortedSet of direct 735 * subclasses as String 736 * 737 * private SortedSet<String> getDirectSubClasses(String concept) { 738 * 739 * String sparqlQueryString; SortedSet<String> subClasses = new TreeSet<String>(); 740 * ResultSet resultSet; 741 * 742 * sparqlQueryString = "SELECT * \n " + "WHERE { \n" + " ?subject ?predicate <" + 743 * concept + "> \n" + "}\n"; 744 * 745 * resultSet = queryAsResultSet(sparqlQueryString); 746 * 747 * @SuppressWarnings("unchecked") List<ResultBinding> bindings = 748 * ResultSetFormatter.toList(resultSet); String subject = ""; String predicate = 749 * ""; 750 * 751 * for (ResultBinding resultBinding : bindings) { 752 * 753 * subject = ((resultBinding.get("subject").toString())); predicate = 754 * ((resultBinding.get("predicate").toString())); if (predicate 755 * .equalsIgnoreCase("http://www.w3.org/2000/01/rdf-schema#subClassOf")) { 756 * subClasses.add(subject); } } return subClasses; } 757 * 758 * 759 * 760 * 761 * 762 * 763 * 764 */ 765