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