source: Dev/branches/rest-dojo-ui/Demo/rdfapi/sparql/Query.php @ 312

Last change on this file since 312 was 312, checked in by jkraaijeveld, 13 years ago
File size: 14.8 KB
Line 
1<?php
2require_once RDFAPI_INCLUDE_DIR . 'sparql/GraphPattern.php';
3
4/**
5* The Class Query represents a SPARQL query.
6*
7*
8* @author  Tobias Gauss <tobias.gauss@web.de>
9* @version $Id$
10* @license http://www.gnu.org/licenses/lgpl.html LGPL
11*
12* @package sparql
13*/
14class Query extends Object
15{
16    /**
17    * The BASE part of the SPARQL query.
18    * @var string
19    */
20    protected $base;
21
22    /**
23    * Original SPARQL query string
24    * @var string
25    */
26    protected $queryString = null;
27
28    /**
29    * Array that contains used prefixes and namespaces.
30    * Key is the prefix, value the namespace.
31    *
32    * @example
33    * array(8) {
34    *  ["rdf"] => string(43) "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
35    *  ["rdfs"]=> string(37) "http://www.w3.org/2000/01/rdf-schema#"
36    * }
37    *
38    * @var array
39    */
40    public $prefixes = array();
41
42    /**
43    * Array of result variables that shall be returned.
44    * E.g. "?name", "?mbox"
45    *
46    * @var array
47    */
48    protected $resultVars = array();
49
50    /**
51    * What form/type of result should be returned.
52    *
53    * One of:
54    * - "ask"
55    * - "count"
56    * - "construct"
57    * - "describe"
58    * - "select"
59    * - "select distinct"
60    *
61    * @var string
62    * @see http://www.w3.org/TR/rdf-sparql-query/#QueryForms
63    */
64    protected $resultForm = null;
65
66    /**
67    * Contains the result part of the SPARQL query.
68    * Array of GraphPattern
69    *
70    * @var array
71    */
72    protected $resultPart = array();
73
74    /**
75    *  Contains the FROM part of the SPARQL query.
76    * @var array
77    */
78    protected $fromPart = array();
79
80    /**
81    * Contains the FROM NAMED part of the SPARQL query.
82    * @var array
83    */
84    protected $fromNamedPart = array();
85
86    /**
87    * Optional solution modifier of the query.
88    * Array with three keys:
89    *  "order by", "limit", "offset"
90    * If they are not set, their value is null
91    *
92    * "order by" can be an array with subarrays, each of those
93    *  subarrays having two keys: "val" and "type".
94    *  "val" determines the variable ("?mbox"), "type" is
95    *  "asc" or "desc"
96    *
97    * @var array
98    */
99    protected $solutionModifier = array();
100
101    /**
102    *  Blanknode counter.
103    * How many blank nodes are in $resultPart
104    *
105    * @var int
106    */
107    protected $bnodeCounter = 0;
108
109    /**
110    * GraphPattern counter.
111    * How many GraphPattern are in $resultPart
112    *
113    * @var int
114    */
115    public $graphPatternCounter = 0;
116
117    /**
118    * List of all vars used in the query.
119    * Key is the variable (e.g. "?x"), value
120    * is boolean true
121    *
122    * @var array
123    */
124    public $usedVars = array();
125
126    /**
127    * If the query type is CONSTRUCT this variable contains the
128    * CONSTRUCT graph pattern.
129    */
130    protected $constructPattern = null;
131
132    /**
133    * TRUE if the query is empty FALSE if not.
134    *
135    * @var boolean
136    */
137    public $isEmpty = null;
138
139    /**
140    *   Language of variables. NULL if the variable has no
141    *   language tag (e.g. @en) set.
142    *   $varname => $language tag
143    *   @var array
144    */
145    public $varLanguages = array();
146
147    /**
148    *   Datatype of variables. NULL if the variable has no
149    *   data type (e.g. ^^xsd::integer) set.
150    *   $varname => $datatype
151    *   @var array
152    */
153    public $varDatatypes = array();
154
155
156
157    /**
158    * Constructor
159    */
160    public function Query(){
161        $this->resultForm = null;
162        $this->solutionModifier['order by'] = null;
163        $this->solutionModifier['limit']    = null;
164        $this->solutionModifier['offset']   = null;
165        $this->bnodeCounter = 0;
166        $this->graphPatternCounter = 0;
167
168    }
169
170    /**
171    * Returns the BASE part of the query.
172    *
173    * @return String
174    */
175    public function getBase(){
176        return $this->base;
177    }
178
179    /**
180    * Returns the prefix map of the query.
181    *
182    * @return Array
183    */
184    public function getPrefixes(){
185        return $this->prefixes;
186    }
187   
188    /**
189    * Returns a list containing the result vars.
190    *
191    * @return Array
192    */
193    public function getResultVar($strName) {
194        foreach ($this->resultVars as $var) {
195            if ($var->getVariable() == $strName) {
196                return $var;
197            }
198        }
199        return false;
200    }
201
202    /**
203    * Returns a list containing the result vars.
204    *
205    * @return Array
206    */
207    public function getResultVars(){
208        return $this->resultVars;
209    }
210
211    /**
212    * Returns the type the result shall have.
213    * E.g. "select", "select distinct", "ask", ...
214    *
215    * @see $resultForm
216    *
217    * @return string
218    */
219    public function getResultForm(){
220        return $this->resultForm;
221    }
222
223    /**
224    * Returns a list containing the graph patterns of the query.
225    *
226    * @return Array
227    */
228    public function getResultPart(){
229        return $this->resultPart;
230    }
231
232    /**
233    * Returns the FROM clause of the query.
234    *
235    * @return String
236    */
237    public function getFromPart(){
238        return $this->fromPart;
239    }
240
241    /**
242    * Returns the FROM NAMED clause of the query.
243    *
244    * @return Array
245    */
246    public function getFromNamedPart(){
247        return $this->fromNamedPart;
248    }
249
250    /**
251    * Returns $isEmpty variable
252    * @return boolean
253    */
254    public function isEmpty() {
255        return $this->isEmpty;
256    }
257
258    /**
259    * Returns an unused Bnode label.
260    *
261    * @return String
262    */
263    public function getBlanknodeLabel(){
264        return "_:bN".$this->bnodeCounter++;
265    }
266
267
268    /**
269    * Sets the base part.
270    *
271    * @param String $base
272    * @return void
273    */
274    public function setBase($base){
275        $this->base = $base;
276    }
277
278
279    /**
280    * Adds a prefix to the list of prefixes.
281    *
282    * @param  String $prefix
283    * @param  String $label
284    * @return void
285    */
286    public function addPrefix($prefix, $label){
287        $this->prefixes[$prefix]= $label;
288    }
289
290    /**
291    * Adds a variable to the list of result variables.
292    *
293    * @param  String $var
294    * @return void
295    */
296    public function addResultVar($var){
297        $this->resultVars[] = $var;
298        $var->setDatatype($this->getDatatype($var));
299
300        $this->varLanguages[$var->getId()] = self::getLanguageTag($var);
301        $this->varDatatypes[$var->getId()] = $this->getDatatype($var);
302    }
303
304
305    /**
306    * Sets the result form.
307    *
308    * @param  String $form
309    * @return void
310    */
311    public function setResultForm($form){
312        $this->resultForm = strtolower($form);
313    }
314
315
316    /**
317    * Sets the result part.
318    *
319    * @param  array Array of graph patterns
320    */
321    public function setResultPart($resultPart) {
322        $this->resultPart = $resultPart;
323    }
324
325    /**
326    * Adds a graph pattern to the result part.
327    *
328    * @param  GraphPattern $pattern
329    * @return void
330    */
331    public function addGraphPattern($pattern){
332        $pattern->setId($this->graphPatternCounter);
333        $this->resultPart[] = $pattern;
334        $this->graphPatternCounter++;
335    }
336
337    /**
338    * Adds a construct graph pattern to the query.
339    *
340    * @param  GraphPattern $pattern
341    * @return void
342    */
343    public function addConstructGraphPattern($pattern){
344        $this->constructPattern = $pattern;
345    }
346
347
348    /**
349    * Adds a graphuri to the from part.
350    *
351    * @param  String $graphURI
352    * @return void
353    */
354    public function addFrom($graphURI){
355        $this->fromPart[] = $graphURI;
356    }
357
358    /**
359    * Adds a graphuri to the from named part.
360    *
361    * @param  String $graphURI
362    * @return void
363    */
364    public function addFromNamed($graphURI){
365        $this->fromNamedPart[] = $graphURI;
366    }
367
368    /**
369    * Sets a solution modifier.
370    *
371    * @param  String $name
372    * @param  Value  $value
373    * @return void
374    */
375    public function setSolutionModifier($name, $value){
376        $this->solutionModifier[$name] = $value;
377    }
378
379
380    /**
381    * Generates a new GraphPattern. If it is a CONSTRUCT graph pattern
382    * $constr has to set to TRUE, FALSE if not.
383    *
384    * @param  boolean $constr
385    * @return GraphPattern
386    */
387    public function getNewPattern($constr = false){
388        $pattern = new GraphPattern();
389        if ($constr) {
390            $this->addConstructGraphPattern($pattern);
391        } else {
392            $this->addGraphPattern($pattern);
393        }
394        return $pattern;
395    }
396
397    /**
398    * Adds a new variable to the variable list.
399    *
400    * @param  String $var
401    * @return void
402    */
403    public function addUsedVar($var){
404        $this->usedVars[$var]=true;
405    }
406
407    /**
408    * Returns a list with all used variables.
409    *
410    * @return Array
411    */
412    public function getAllVars(){
413        return array_keys($this->usedVars);
414    }
415
416    /**
417    * Gets the solution modifiers of the query.
418    * $solutionModifier['order by'] = value
419    *                  ['limit']    = vlaue
420    *                  ['offset']   = value
421    *
422    *
423    * @return Array
424    */
425    public function getSolutionModifier(){
426        return $this->solutionModifier;
427    }
428
429
430    /**
431    * Returns the construvtGraphPattern of the query if there is one.
432    *
433    * @return GraphPattern
434    */
435    public function getConstructPattern(){
436        return $this->constructPattern;
437    }
438
439
440
441    /**
442    *   Returns a list of variables used in the construct patterns.
443    *
444    *   @return array Array of variable names, unique.
445    */
446    public function getConstructPatternVariables()
447    {
448        $arVars = array();
449/*
450        if (count($this->resultPart) > 0) {
451            foreach ($this->resultPart as $pattern) {
452                $arVars = array_merge($arVars, $pattern->getVariables());
453            }
454        }
455*/
456        if ($this->constructPattern) {
457            $arVars = array_merge($arVars, $this->constructPattern->getVariables());
458        }
459
460        return array_unique($arVars);
461    }//public function getConstructPatternVariables()
462
463
464
465    /**
466    *   Returns the language of a variable if the tag is set (e.g. @en)
467    *   Returns NULL if no language is set.
468    *
469    *   @param string Sparql variable name
470    *   @return mixed NULL or language tag
471    */
472    public static function getLanguageTag($var)
473    {
474        $nAt = strpos($var, '@');
475        if ($nAt === false) {
476            return null;
477        }
478        //in case @ and ^^ are combined
479        $nHatHat = strpos($var, '^^', $nAt + 1);
480        if ($nHatHat === false) {
481            $tag = substr($var, $nAt + 1);
482        } else {
483            $tag = substr($var, $nAt + 1, $nHatHat - $nAt - 1);
484        }
485        return $tag;
486    }//public static function getLanguageTag($var)
487
488
489
490    /**
491    *   Returns the datatype of a variable if it is set.
492    *
493    *   @param string Sparql variable name
494    *   @return mixed NULL or datatype
495    */
496    public function getDatatype($var)
497    {
498        $nHatHat = strpos($var, '^^');
499        if ($nHatHat === false) {
500            return null;
501        }
502        $nAt = strpos($var, '@', $nHatHat + 2);
503        if ($nAt === false) {
504            $type = substr($var, $nHatHat + 2);
505        } else {
506            $type = substr($var, $nHatHat + 2, $nAt - $nHatHat - 2);
507        }
508
509        $fullUri = $this->getFullUri($type);
510        if ($fullUri === false) {
511            $fullUri = $type;
512            if ($fullUri[0] == '<' && substr($fullUri, -1) == '>') {
513                $fullUri = substr($fullUri, 1, -1);
514            }
515        }
516
517        return $fullUri;
518    }//public function getDatatype($var)
519
520
521
522    /**
523    * Gets the full URI of a qname token.
524    *
525    * @param  string $token
526    * @return string The complete URI of a given token, false if $token is not
527    *                a qname or the prefix is not defined
528    */
529    public function getFullUri($token)
530    {
531        $pattern="/^([^:]*):([^:]*)$/";
532        if (preg_match($pattern, $token, $hits) > 0) {
533
534            if (isset($this->prefixes{$hits{1}})) {
535                return substr($this->base, 1, -1)
536                     . $this->prefixes{$hits{1}}
537                     . $hits{2};
538            }
539            if ($hits{1}=='_') {
540                return "_".$hits{2};
541            }
542        }
543
544        return false;
545    }
546
547
548
549    /**
550    *   Checks if the query is complete
551    *   (so that querying is possible)
552    *
553    *   @return boolean true if the query is complete
554    */
555    public function isComplete()
556    {
557        if ($this->resultForm === null) {
558            return false;
559        }
560        //TODO: maybe check selected vars and construct pattern depending
561        // on the resultform
562        return true;
563    }//public function isIncomplete()
564
565
566
567    /**
568    * Sets the orignal query string
569    *
570    * @param string $queryString SPARQL query string
571    */
572    public function setQueryString($queryString)
573    {
574        $this->queryString = $queryString;
575    }//public function setQueryString($queryString)
576
577
578
579    /**
580    * Returns the orignal query string
581    *
582    * @return string SPARQL query string
583    */
584    public function getQueryString()
585    {
586        return $this->queryString;
587    }//public function getQueryString()
588
589}// end class: Query.php
590
591
592
593class Query_ResultVariable
594{
595    public $variable = null;
596    public $datatype = null;
597    public $language = null;
598    public $alias    = null;
599    public $func     = null;
600
601
602    public function __construct($variable)
603    {
604        $this->variable = $variable;
605        $this->language = Query::getLanguageTag($variable);
606    }
607
608
609
610    public function setAlias($alias)
611    {
612        $this->alias = $alias;
613    }
614
615
616
617    public function setFunc($func)
618    {
619        $this->func = $func;
620    }
621
622
623
624    public function setDatatype($datatype)
625    {
626        $this->datatype = $datatype;
627    }
628
629
630
631    public function getId()
632    {
633        //FIXME
634        return $this->variable;
635    }
636
637
638
639    public function getFunc()
640    {
641        return $this->func;
642    }
643
644
645
646    public function getLanguage()
647    {
648        return $this->language;
649    }
650
651
652
653    public function getDatatype()
654    {
655        return $this->datatype;
656    }
657
658
659
660    public function getName()
661    {
662        if ($this->alias !== null) {
663            return $this->alias;
664        }
665        //FIXME: support for nested(functions())
666        return $this->variable;
667    }
668
669
670
671    public function getVariable()
672    {
673        return $this->variable;
674    }
675
676
677
678    public function __toString()
679    {
680        return $this->getName();
681    }
682
683}//class Query_ResultVariable
684
685?>
Note: See TracBrowser for help on using the repository browser.