Completed
Push — master ( b05d7f...1e24b8 )
by Henri
03:25
created

Model::getVocabularyByGraph()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 21
rs 8.7624
cc 5
eloc 13
nc 8
nop 2
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 21 and the first side effect is on line 11.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Copyright (c) 2012 Aalto University and University of Helsinki
4
 * MIT License
5
 * see LICENSE.txt for more information
6
 */
7
8
/**
9
 * Setting some often needed namespace prefixes
10
 */
11
EasyRdf_Namespace::set('skosmos', 'http://purl.org/net/skosmos#');
12
EasyRdf_Namespace::set('void', 'http://rdfs.org/ns/void#');
13
EasyRdf_Namespace::set('skosext', 'http://purl.org/finnonto/schema/skosext#');
14
EasyRdf_Namespace::set('isothes', 'http://purl.org/iso25964/skos-thes#');
15
16
/**
17
 * Model provides access to the data.
18
 * @property EasyRdf_Graph $graph
19
 * @property GlobalConfig $global_config
20
 */
21
class Model
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
22
{
23
    /** EasyRdf_Graph graph instance */
24
    private $graph;
25
    /** cache for Vocabulary objects */
26
    private $all_vocabularies = null;
27
    /** cache for Vocabulary objects */
28
    private $vocabs_by_graph = null;
29
    /** cache for Vocabulary objects */
30
    private $vocabs_by_urispace = null;
31
    /** how long to store retrieved URI information in APC cache */
32
    private $URI_FETCH_TTL = 86400; // 1 day
33
    private $global_config;
34
35
    /**
36
     * Initializes the Model object
37
     */
38
    public function __construct($config)
39
    {
40
        $this->global_config = $config;
41
        $this->initializeVocabularies();
42
    }
43
44
    /**
45
     * Returns the GlobalConfig object given to the Model as a constructor parameter.
46
     * @return GlobalConfig
47
     */
48
    public function getConfig() {
49
      return $this->global_config;
50
    }
51
52
    /**
53
     * Initializes the configuration from the vocabularies.ttl file
54
     */
55
    private function initializeVocabularies()
56
    {
57
        if (!file_exists($this->getConfig()->getVocabularyConfigFile())) {
58
            throw new Exception($this->getConfig()->getVocabularyConfigFile() . ' is missing, please provide one.');
59
        }
60
61
        try {
62
            // use APC user cache to store parsed vocabularies.ttl configuration
63
            if (function_exists('apc_store') && function_exists('apc_fetch')) {
64
                $key = realpath($this->getConfig()->getVocabularyConfigFile()) . ", " . filemtime($this->getConfig()->getVocabularyConfigFile());
65
                $this->graph = apc_fetch($key);
66
                if ($this->graph === false) { // was not found in cache
67
                    $this->graph = new EasyRdf_Graph();
68
                    $this->graph->parse(file_get_contents($this->getConfig()->getVocabularyConfigFile()));
69
                    apc_store($key, $this->graph);
70
                }
71
            } else { // APC not available, parse on every request
72
                $this->graph = new EasyRdf_Graph();
73
                $this->graph->parse(file_get_contents($this->getConfig()->getVocabularyConfigFile()));
74
            }
75
        } catch (Exception $e) {
76
            echo "Error: " . $e->getMessage();
77
        }
78
    }
79
80
    /**
81
     * Return the version of this Skosmos installation, or "unknown" if
82
     * it cannot be determined. The version information is based on Git tags.
83
     * @return string version
84
     */
85
    public function getVersion()
86
    {
87
        $ver = null;
88
        if (file_exists('.git')) {
89
            $ver = shell_exec('git describe --tags');
90
        }
91
92
        if ($ver === null) {
93
            return "unknown";
94
        }
95
96
        return $ver;
97
    }
98
99
    /**
100
     * Return all the vocabularies available.
101
     * @param boolean $categories whether you want everything included in a subarray of
102
     * a category.
103
     * @param boolean $shortname set to true if you want the vocabularies sorted by 
104
     * their shortnames instead of ther titles.
105
     */
106
    public function getVocabularyList($categories = true, $shortname = false)
107
    {
108
        $cats = $this->getVocabularyCategories();
109
        $ret = array();
110
        foreach ($cats as $cat) {
111
            $catlabel = $cat->getTitle();
112
113
            // find all the vocabs in this category
114
            $vocs = array();
115
            foreach ($cat->getVocabularies() as $voc) {
116
                $vocs[$shortname ? $voc->getConfig()->getShortname() : $voc->getConfig()->getTitle()] = $voc;
117
            }
118
            uksort($vocs, 'strcoll');
119
120
            if (sizeof($vocs) > 0 && $categories) {
121
                $ret[$catlabel] = $vocs;
122
            } elseif (sizeof($vocs) > 0) {
123
                $ret = array_merge($ret, $vocs);
124
            }
125
126
        }
127
128
        if (!$categories) {
129
            uksort($ret, 'strcoll');
130
        }
131
132
        return $ret;
133
    }
134
135
    /**
136
     * Return all types (RDFS/OWL classes) present in the specified vocabulary or all vocabularies.
137
     * @return array Array with URIs (string) as key and array of (label, superclassURI) as value
138
     */
139
    public function getTypes($vocid = null, $lang = null)
140
    {
141
        $sparql = (isset($vocid)) ? $this->getVocabulary($vocid)->getSparql() : $this->getDefaultSparql();
142
        $result = $sparql->queryTypes($lang);
143
144
        foreach ($result as $uri => $values) {
145
            if (empty($values)) {
146
                $shorteneduri = EasyRdf_Namespace::shorten($uri);
147
                if ($shorteneduri !== null) {
148
                    $trans = gettext($shorteneduri);
149
                    if ($trans) {
150
                        $result[$uri] = array('label' => $trans);
151
                    }
152
                }
153
            }
154
        }
155
156
        return $result;
157
    }
158
159
    /**
160
     * Return the languages present in the configured vocabularies.
161
     * @return array Array with lang codes (string)
162
     */
163
    public function getLanguages($lang)
164
    {
165
        $vocabs = $this->getVocabularyList(false);
166
        $ret = array();
167
        foreach ($vocabs as $vocab) {
168
            foreach ($vocab->getConfig()->getLanguages() as $langcode) {
169
                $langlit = Punic\Language::getName($langcode, $lang);
170
                $ret[$langlit] = $langcode;
171
            }
172
        }
173
        ksort($ret);
174
        return array_unique($ret);
175
    }
176
177
    /**
178
     * returns a concept's RDF data in downloadable format
179
     * @param string $vocid vocabulary id, or null for global data (from all vocabularies)
180
     * @param string $uri concept URI
181
     * @param string $format the format in which you want to get the result, currently this function supports
182
     * text/turtle, application/rdf+xml and application/json
183
     * @return string RDF data in the requested serialization
184
     */
185
    public function getRDF($vocid, $uri, $format)
186
    {
187
188
        if ($format == 'text/turtle') {
189
            $retform = 'turtle';
190
            $serialiser = new EasyRdf_Serialiser_Turtle();
191
        } elseif ($format == 'application/ld+json' || $format == 'application/json') {
192
            $retform = 'jsonld'; // serve JSON-LD for both JSON-LD and plain JSON requests
193
            $serialiser = new EasyRdf_Serialiser_JsonLd();
194
        } else {
195
            $retform = 'rdfxml';
196
            $serialiser = new EasyRdf_Serialiser_RdfXml();
197
        }
198
199
        if ($vocid !== null) {
200
            $vocab = $this->getVocabulary($vocid);
201
            $sparql = $vocab->getSparql();
202
            $arrayClass = $vocab->getConfig()->getArrayClassURI();
203
            $vocabs = array($vocab);
204
        } else {
205
            $sparql = $this->getDefaultSparql();
206
            $arrayClass = null;
207
            $vocabs = null;
208
        }
209
        $result = $sparql->queryConceptInfo($uri, $arrayClass, $vocabs, true);
210
211
        return $serialiser->serialise($result, $retform);
212
    }
213
214
    /**
215
     * Makes a SPARQL-query to the endpoint that retrieves concept
216
     * references as it's search results.
217
     * @param string $term the term that is looked for eg. 'cat'.
218
     * @param mixed $vocids vocabulary id eg. 'yso', array of such ids for multi-vocabulary search, or null for global search.
219
     * @param string $lang language code to show labels in, eg. 'fi' for Finnish.
220
     * @param string $search_lang language code used for matching, eg. 'fi' for Finnish, null for any language
221
     * @param string $type limit search to concepts of the given type
222
     * @param string $parent limit search to concepts which have the given concept as parent in the transitive broader hierarchy
223
     * @param string $group limit search to concepts which are in the given group
224
     * @param int $offset optional parameter for search offset.
225
     * @param int $limit optional paramater for maximum amount of results.
226
     * @param boolean $hidden include matches on hidden labels (default: true).
227
     * @param array $fields extra fields to include in the result (array of strings). (default: null = none)
228
     * @return array search results
229
     */
230
    public function searchConcepts($term, $vocids, $lang, $search_lang, $type = null, $parent = null, $group = null, $offset = 0, $limit = null, $hidden = true, $fields = null)
231
    {
232
        if ($limit === null) {
233
            $limit = $this->getConfig()->getDefaultSearchLimit();
234
        }
235
        $term = trim($term);
236
        if ($term == "" || !preg_match('/[^*]/', $term)) {
237
            return array();
238
        }
239
        // don't even try to search for empty prefix
240
241
        // make vocids an array in every case
242
        if ($vocids === null) {
243
            $vocids = array();
244
        }
245
246
        if (!is_array($vocids)) {
247
            $vocids = array($vocids);
248
        }
249
250
        $vocabs = array();
251
        foreach ($vocids as $vocid) {
252
            $vocabs[] = $this->getVocabulary($vocid);
253
        }
254
255 View Code Duplication
        if (sizeof($vocids) == 1) { // search within vocabulary
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
            $voc = $vocabs[0];
257
            $sparql = $voc->getSparql();
258
            $arrayClass = $voc->getConfig()->getArrayClassURI();
259
        } else { // multi-vocabulary or global search
260
            $voc = null;
261
            $arrayClass = null;
262
            $sparql = $this->getDefaultSparql();
263
        }
264
        if ($type === null) {
265
            $type = array('skos:Concept');
266
        }
267
268
        $results = $sparql->queryConcepts($term, $vocabs, $lang, $search_lang, $limit, $offset, $arrayClass, $type, $parent, $group, $hidden, $fields);
269
        $ret = array();
270
271
        foreach ($results as $hit) {
272
            if (sizeof($vocids) == 1) {
273
                $hit['vocab'] = $vocids[0];
274
            } else {
275
                try {
276
                    $voc = $this->getVocabularyByGraph($hit['graph']);
277
                    $hit['vocab'] = $voc->getId();
278
                } catch (Exception $e) {
279
                    trigger_error($e->getMessage(), E_USER_WARNING);
280
                    $voc = null;
281
                    $hit['vocab'] = "???";
282
                }
283
            }
284
            unset($hit['graph']);
285
286
            $hit['voc'] = $voc;
287
288
            // if uri is a external vocab uri that is included in the current vocab
289
            $realvoc = $this->guessVocabularyFromURI($hit['uri']);
290
            if ($realvoc != $voc) {
291
                unset($hit['localname']);
292
                $hit['exvocab'] = ($realvoc !== null) ? $realvoc->getId() : "???";
293
            }
294
295
            $ret[] = $hit;
296
        }
297
298
        return $ret;
299
    }
300
301
    /**
302
     * Function for performing a search for concepts and their data fields.
303
     * @param string $term searchterm eg. 'cat'
304
     * @param mixed $vocids vocabulary id eg. 'yso', array of such ids for multi-vocabulary search, or null for global search.
305
     * @param string $lang language code of returned labels, eg. 'fi'
306
     * @param string $search_lang language code used for matching, eg. 'fi', or null for anything
307
     * @param integer $offset used for offsetting the result set eg. '20'
308
     * @param integer $limit upper count for the search results eg. '10'
309
     * @param string $type limit search to concepts of the given type
310
     * @param string $parent limit search to concepts which have the given concept as parent in the transitive broader hierarchy
311
     * @param string $group limit search to concepts which are in the given group
312
     * @return array array with keys 'count' and 'results'
313
     */
314
    public function searchConceptsAndInfo($term, $vocids, $lang, $search_lang, $offset = 0, $limit = 20, $type = null, $parent = null, $group = null)
315
    {
316
        // make vocids an array in every case
317
        if ($vocids === null) {
318
            $vocids = array();
319
        }
320
321
        if (!is_array($vocids)) {
322
            $vocids = array($vocids);
323
        }
324
325
        $allhits = $this->searchConcepts($term, $vocids, $lang, $search_lang, $type, $parent, $group, 0, 0);
326
        $hits = array_slice($allhits, $offset, $limit);
327
328
        $uris = array();
329
        $vocabs = array();
330
        $uniqueVocabs = array();
331
        foreach ($hits as $hit) {
332
            $uniqueVocabs[$hit['voc']->getId()] = $hit['voc']->getId();
333
            $vocabs[] = $hit['voc'];
334
            $uris[] = $hit['uri'];
335
        }
336 View Code Duplication
        if (sizeof($uniqueVocabs) == 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
337
            $voc = $vocabs[0];
338
            $sparql = $voc->getSparql();
339
            $arrayClass = $voc->getConfig()->getArrayClassURI();
340
        } else {
341
            $arrayClass = null;
342
            $sparql = $this->getDefaultSparql();
343
        }
344
        $ret = $sparql->queryConceptInfo($uris, $arrayClass, $vocabs, null, $search_lang);
345
346
        // For marking that the concept has been found through an alternative label, hidden
347
        // label or a label in another language
348
        foreach ($hits as $idx => $hit) {
349
            if (isset($hit['altLabel']) && isset($ret[$idx])) {
350
                $ret[$idx]->setFoundBy($hit['altLabel'], 'alt');
351
            }
352
353
            if (isset($hit['hiddenLabel']) && isset($ret[$idx])) {
354
                $ret[$idx]->setFoundBy($hit['hiddenLabel'], 'hidden');
355
            }
356
357
            if (isset($hit['matchedPrefLabel'])) {
358
                $ret[$idx]->setFoundBy($hit['matchedPrefLabel'], 'lang');
359
            }
360
361
            if ($ret[$idx]) {
362
                $ret[$idx]->setContentLang($hit['lang']);
363
            }
364
365
        }
366
367
        return array('count' => sizeof($allhits), 'results' => $ret);
368
    }
369
370
    /**
371
     * Creates dataobjects from an input array.
372
     * @param string $class the type of class eg. 'Vocabulary'.
373
     * @param array $resarr contains the EasyRdf_Resources.
374
     */
375
    private function createDataObjects($class, $resarr)
376
    {
377
        $ret = array();
378
        foreach ($resarr as $res) {
379
            $ret[] = new $class($this, $res);
380
        }
381
382
        return $ret;
383
    }
384
385
    /**
386
     * Returns the cached vocabularies.
387
     * @return array of Vocabulary dataobjects
388
     */
389
    public function getVocabularies()
390
    {
391
        if ($this->all_vocabularies === null) { // initialize cache
392
            $vocs = $this->graph->allOfType('skosmos:Vocabulary');
393
            $this->all_vocabularies = $this->createDataObjects("Vocabulary", $vocs);
394
            foreach ($this->all_vocabularies as $voc) {
395
                // register vocabulary ids as RDF namespace prefixes
396
                $prefix = preg_replace('/\W+/', '', $voc->getId()); // strip non-word characters
397
                try {
398
                    if ($prefix != '' && EasyRdf_Namespace::get($prefix) === null) // if not already defined
399
                    {
400
                        EasyRdf_Namespace::set($prefix, $voc->getUriSpace());
401
                    }
402
403
                } catch (Exception $e) {
404
                    // not valid as namespace identifier, ignore
405
                }
406
            }
407
        }
408
409
        return $this->all_vocabularies;
410
    }
411
412
    /**
413
     * Returns the cached vocabularies from a category.
414
     * @param EasyRdf_Resource $cat the category in question
415
     * @return array of vocabulary dataobjects
416
     */
417
    public function getVocabulariesInCategory($cat)
418
    {
419
        $vocs = $this->graph->resourcesMatching('dc:subject', $cat);
420
421
        return $this->createDataObjects("Vocabulary", $vocs);
422
    }
423
424
    /**
425
     * Creates dataobjects of all the different vocabulary categories (Health etc.).
426
     * @return array of Dataobjects of the type VocabularyCategory.
427
     */
428
    public function getVocabularyCategories()
429
    {
430
        $cats = $this->graph->allOfType('skos:Concept');
431
432
        return $this->createDataObjects("VocabularyCategory", $cats);
433
    }
434
435
    /**
436
     * Returns the label defined in vocabularies.ttl with the appropriate language.
437
     * @param string $lang language code of returned labels, eg. 'fi'
438
     * @return string the label for vocabulary categories.
439
     */
440
    public function getClassificationLabel($lang)
441
    {
442
        $cats = $this->graph->allOfType('skos:ConceptScheme');
443
        $label = $cats ? $cats[0]->label($lang) : null;
444
445
        return $label;
446
    }
447
448
    /**
449
     * Returns a single cached vocabulary.
450
     * @param string $vocid the vocabulary id eg. 'mesh'.
451
     * @return vocabulary dataobject
452
     */
453
    public function getVocabulary($vocid)
454
    {
455
        $vocs = $this->getVocabularies();
456
        foreach ($vocs as $voc) {
457
            if ($voc->getId() == $vocid) {
458
                return $voc;
459
            }
460
        }
461
        throw new Exception("Vocabulary id '$vocid' not found in configuration.");
462
    }
463
464
    /**
465
     * Return the vocabulary that is stored in the given graph on the given endpoint.
466
     *
467
     * @param $graph string graph URI
468
     * @param $endpoint string endpoint URL (default SPARQL endpoint if omitted)
469
     * @return Vocabulary vocabulary of this URI, or null if not found
470
     */
471
    public function getVocabularyByGraph($graph, $endpoint = null)
472
    {
473
        if ($endpoint === null) {
474
            $endpoint = $this->getConfig()->getDefaultEndpoint();
475
        }
476
        if ($this->vocabs_by_graph === null) { // initialize cache
477
            $this->vocabs_by_graph = array();
478
            foreach ($this->getVocabularies() as $voc) {
479
                $key = json_encode(array($voc->getGraph(), $voc->getEndpoint()));
480
                $this->vocabs_by_graph[$key] = $voc;
481
            }
482
        }
483
484
        $key = json_encode(array($graph, $endpoint));
485
        if (array_key_exists($key, $this->vocabs_by_graph)) {
486
            return $this->vocabs_by_graph[$key];
487
        } else {
488
            throw new Exception("no vocabulary found for graph $graph and endpoint $endpoint");
489
        }
490
491
    }
492
493
    /**
494
     * Guess which vocabulary a URI originates from, based on the declared
495
     * vocabulary URI spaces.
496
     *
497
     * @param $uri string URI to search
498
     * @return Vocabulary vocabulary of this URI, or null if not found
499
     */
500
    public function guessVocabularyFromURI($uri)
501
    {
502
        if ($this->vocabs_by_urispace === null) { // initialize cache
503
            $this->vocabs_by_urispace = array();
504
            foreach ($this->getVocabularies() as $voc) {
505
                $this->vocabs_by_urispace[$voc->getUriSpace()] = $voc;
506
            }
507
        }
508
509
        // try to guess the URI space and look it up in the cache
510
        $res = new EasyRdf_Resource($uri);
511
        $namespace = substr($uri, 0, -strlen($res->localName()));
512
        if (array_key_exists($namespace, $this->vocabs_by_urispace)) {
513
            return $this->vocabs_by_urispace[$namespace];
514
        }
515
516
        // didn't work, try to match with each URI space separately
517
        foreach ($this->vocabs_by_urispace as $urispace => $voc) {
518
            if (strpos($uri, $urispace) === 0) {
519
                return $voc;
520
            }
521
        }
522
523
        // not found
524
        return null;
525
    }
526
527
    /**
528
     * Get the label for a resource, preferring 1. the given language 2. configured languages 3. any language.
529
     * @param EasyRdf_Resource $res resource whose label to return
530
     * @param string $lang preferred language
531
     * @return EasyRdf_Literal label as an EasyRdf_Literal object, or null if not found
532
     */
533
    public function getResourceLabel($res, $lang)
534
    {
535
        $langs = array_merge(array($lang), array_keys($this->config->getLanguages()));
0 ignored issues
show
Bug introduced by
The property config does not seem to exist. Did you mean global_config?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
536
        foreach ($langs as $l) {
537
            $label = $res->label($l);
538
            if ($label !== null) {
539
                return $label;
540
            }
541
542
        }
543
        return $res->label(); // desperate check for label in any language; will return null if even this fails
544
    }
545
546
    private function fetchResourceFromUri($uri)
547
    {
548
        try {
549
            // change the timeout setting for external requests
550
            $httpclient = EasyRdf_Http::getDefaultHttpClient();
551
            $httpclient->setConfig(array('timeout' => $this->getConfig()->getHttpTimeout()));
552
            EasyRdf_Http::setDefaultHttpClient($httpclient);
553
554
            $client = EasyRdf_Graph::newAndLoad(EasyRdf_Utils::removeFragmentFromUri($uri));
555
            return $client->resource($uri);
556
        } catch (Exception $e) {
557
            return null;
558
        }
559
    }
560
561
    public function getResourceFromUri($uri)
562
    {
563
        EasyRdf_Format::unregister('json'); // prevent parsing errors for sources which return invalid JSON
564
        // using apc cache for the resource if available
565
        if (function_exists('apc_store') && function_exists('apc_fetch')) {
566
            $key = 'fetch: ' . EasyRdf_Utils::removeFragmentFromUri($uri);
567
            $resource = apc_fetch($key);
568
            if ($resource === null || $resource === false) { // was not found in cache, or previous request failed
569
                $resource = $this->fetchResourceFromUri($uri);
570
                apc_store($key, $resource, $this->URI_FETCH_TTL);
571
            }
572
        } else { // APC not available, parse on every request
573
            $resource = $this->fetchResourceFromUri($uri);
574
        }
575
        return $resource;
576
    }
577
578
    /**
579
     * Returns a SPARQL endpoint object.
580
     * @param string $dialect eg. 'JenaText'.
581
     * @param string $endpoint url address of endpoint
582
     * @param string $graph uri for the target graph.
583
     */
584
    public function getSparqlImplementation($dialect, $endpoint, $graph)
585
    {
586
        $classname = $dialect . "Sparql";
587
588
        return new $classname($endpoint, $graph, $this);
589
    }
590
591
    /**
592
     * Returns a SPARQL endpoint object using the default implementation set in the config.inc.
593
     */
594
    public function getDefaultSparql()
595
    {
596
        return $this->getSparqlImplementation($this->getConfig()->getDefaultSparqlDialect(), $this->getConfig()->getDefaultEndpoint(), '?graph');
597
    }
598
599
}
600