Version 1
[yaffs-website] / vendor / easyrdf / easyrdf / lib / EasyRdf / Sparql / Result.php
diff --git a/vendor/easyrdf/easyrdf/lib/EasyRdf/Sparql/Result.php b/vendor/easyrdf/easyrdf/lib/EasyRdf/Sparql/Result.php
new file mode 100644 (file)
index 0000000..22001e9
--- /dev/null
@@ -0,0 +1,384 @@
+<?php
+
+/**
+ * EasyRdf
+ *
+ * LICENSE
+ *
+ * Copyright (c) 2009-2013 Nicholas J Humfrey.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
+ *    promote products derived from this software without specific prior
+ *    written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package    EasyRdf
+ * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license    http://www.opensource.org/licenses/bsd-license.php
+ */
+
+/**
+ * Class for returned for SPARQL SELECT and ASK query responses.
+ *
+ * @package    EasyRdf
+ * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
+ * @license    http://www.opensource.org/licenses/bsd-license.php
+ */
+class EasyRdf_Sparql_Result extends ArrayIterator
+{
+    private $type = null;
+    private $boolean = null;
+
+    private $ordered = null;
+    private $distinct = null;
+    private $fields = array();
+
+    /** A constant for the SPARQL Query Results XML Format namespace */
+    const SPARQL_XML_RESULTS_NS = 'http://www.w3.org/2005/sparql-results#';
+
+    /** Create a new SPARQL Result object
+     *
+     * You should not normally need to create a SPARQL result
+     * object directly - it will be constructed automatically
+     * for you by EasyRdf_Sparql_Client.
+     *
+     * @param string $data      The SPARQL result body
+     * @param string $mimeType  The MIME type of the result
+     */
+    public function __construct($data, $mimeType)
+    {
+        if ($mimeType == 'application/sparql-results+xml') {
+            return $this->parseXml($data);
+        } elseif ($mimeType == 'application/sparql-results+json') {
+            return $this->parseJson($data);
+        } else {
+            throw new EasyRdf_Exception(
+                "Unsupported SPARQL Query Results format: $mimeType"
+            );
+        }
+    }
+
+    /** Get the query result type (boolean/bindings)
+     *
+     * ASK queries return a result of type 'boolean'.
+     * SELECT query return a result of type 'bindings'.
+     *
+     * @return string The query result type.
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /** Return the boolean value of the query result
+     *
+     * If the query was of type boolean then this method will
+     * return either true or false. If the query was of some other
+     * type then this method will return null.
+     *
+     * @return boolean The result of the query.
+     */
+    public function getBoolean()
+    {
+        return $this->boolean;
+    }
+
+    /** Return true if the result of the query was true.
+     *
+     * @return boolean True if the query result was true.
+     */
+    public function isTrue()
+    {
+        return $this->boolean == true;
+    }
+
+    /** Return false if the result of the query was false.
+     *
+     * @return boolean True if the query result was false.
+     */
+    public function isFalse()
+    {
+        return $this->boolean == false;
+    }
+
+    /** Return the number of fields in a query result of type bindings.
+     *
+     * @return integer The number of fields.
+     */
+    public function numFields()
+    {
+        return count($this->fields);
+    }
+
+    /** Return the number of rows in a query result of type bindings.
+     *
+     * @return integer The number of rows.
+     */
+    public function numRows()
+    {
+        return count($this);
+    }
+
+    /** Get the field names in a query result of type bindings.
+     *
+     * @return array The names of the fields in the result.
+     */
+    public function getFields()
+    {
+        return $this->fields;
+    }
+
+    /** Return a human readable view of the query result.
+     *
+     * This method is intended to be a debugging aid and will
+     * return a pretty-print view of the query result.
+     *
+     * @param  string  $format  Either 'text' or 'html'
+     */
+    public function dump($format = 'html')
+    {
+        if ($this->type == 'bindings') {
+            $result = '';
+            if ($format == 'html') {
+                $result .= "<table class='sparql-results' style='border-collapse:collapse'>";
+                $result .= "<tr>";
+                foreach ($this->fields as $field) {
+                    $result .= "<th style='border:solid 1px #000;padding:4px;".
+                               "vertical-align:top;background-color:#eee;'>".
+                               "?$field</th>";
+                }
+                $result .= "</tr>";
+                foreach ($this as $row) {
+                    $result .= "<tr>";
+                    foreach ($this->fields as $field) {
+                        if (isset($row->$field)) {
+                            $result .= "<td style='border:solid 1px #000;padding:4px;".
+                                       "vertical-align:top'>".
+                                       $row->$field->dumpValue($format)."</td>";
+                        } else {
+                            $result .= "<td>&nbsp;</td>";
+                        }
+                    }
+                    $result .= "</tr>";
+                }
+                $result .= "</table>";
+            } else {
+                // First calculate the width of each comment
+                $colWidths = array();
+                foreach ($this->fields as $field) {
+                    $colWidths[$field] = strlen($field);
+                }
+
+                $textData = array();
+                foreach ($this as $row) {
+                    $textRow = array();
+                    foreach ($row as $k => $v) {
+                        $textRow[$k] = $v->dumpValue('text');
+                        $width = strlen($textRow[$k]);
+                        if ($colWidths[$k] < $width) {
+                            $colWidths[$k] = $width;
+                        }
+                    }
+                    $textData[] = $textRow;
+                }
+
+                // Create a horizontal rule
+                $hr = "+";
+                foreach ($colWidths as $k => $v) {
+                    $hr .= "-".str_repeat('-', $v).'-+';
+                }
+
+                // Output the field names
+                $result .= "$hr\n|";
+                foreach ($this->fields as $field) {
+                    $result .= ' '.str_pad("?$field", $colWidths[$field]).' |';
+                }
+
+                // Output each of the rows
+                $result .= "\n$hr\n";
+                foreach ($textData as $textRow) {
+                    $result .= '|';
+                    foreach ($textRow as $k => $v) {
+                        $result .= ' '.str_pad($v, $colWidths[$k]).' |';
+                    }
+                    $result .= "\n";
+                }
+                $result .= "$hr\n";
+
+            }
+            return $result;
+        } elseif ($this->type == 'boolean') {
+            $str = ($this->boolean ? 'true' : 'false');
+            if ($format == 'html') {
+                return "<p>Result: <span style='font-weight:bold'>$str</span></p>";
+            } else {
+                return "Result: $str";
+            }
+        } else {
+            throw new EasyRdf_Exception(
+                "Failed to dump SPARQL Query Results format, unknown type: ". $this->type
+            );
+        }
+    }
+
+    /** Create a new EasyRdf_Resource or EasyRdf_Literal depending
+     *  on the type of data passed in.
+     *
+     * @ignore
+     */
+    protected function newTerm($data)
+    {
+        switch($data['type']) {
+            case 'bnode':
+                return new EasyRdf_Resource('_:'.$data['value']);
+            case 'uri':
+                return new EasyRdf_Resource($data['value']);
+            case 'literal':
+            case 'typed-literal':
+                return EasyRdf_Literal::create($data);
+            default:
+                throw new EasyRdf_Exception(
+                    "Failed to parse SPARQL Query Results format, unknown term type: ".
+                    $data['type']
+                );
+        }
+    }
+
+    /** Parse a SPARQL result in the XML format into the object.
+     *
+     * @ignore
+     */
+    protected function parseXml($data)
+    {
+        $doc = new DOMDocument();
+        $doc->loadXML($data);
+
+        # Check for valid root node.
+        if ($doc->hasChildNodes() == false or
+            $doc->childNodes->length != 1 or
+            $doc->firstChild->nodeName != 'sparql' or
+            $doc->firstChild->namespaceURI != self::SPARQL_XML_RESULTS_NS) {
+            throw new EasyRdf_Exception(
+                "Incorrect root node in SPARQL XML Query Results format"
+            );
+        }
+
+        # Is it the result of an ASK query?
+        $boolean = $doc->getElementsByTagName('boolean');
+        if ($boolean->length) {
+            $this->type = 'boolean';
+            $value = $boolean->item(0)->nodeValue;
+            $this->boolean = $value == 'true' ? true : false;
+            return;
+        }
+
+        # Get a list of variables from the header
+        $head = $doc->getElementsByTagName('head');
+        if ($head->length) {
+            $variables = $head->item(0)->getElementsByTagName('variable');
+            foreach ($variables as $variable) {
+                $this->fields[] = $variable->getAttribute('name');
+            }
+        }
+
+        # Is it the result of a SELECT query?
+        $resultstag = $doc->getElementsByTagName('results');
+        if ($resultstag->length) {
+            $this->type = 'bindings';
+            $results = $resultstag->item(0)->getElementsByTagName('result');
+            foreach ($results as $result) {
+                $bindings = $result->getElementsByTagName('binding');
+                $t = new stdClass();
+                foreach ($bindings as $binding) {
+                    $key = $binding->getAttribute('name');
+                    foreach ($binding->childNodes as $node) {
+                        if ($node->nodeType != XML_ELEMENT_NODE) {
+                            continue;
+                        }
+                        $t->$key = $this->newTerm(
+                            array(
+                                'type' => $node->nodeName,
+                                'value' => $node->nodeValue,
+                                'lang' => $node->getAttribute('xml:lang'),
+                                'datatype' => $node->getAttribute('datatype')
+                            )
+                        );
+                        break;
+                    }
+                }
+                $this[] = $t;
+            }
+            return $this;
+        }
+
+        throw new EasyRdf_Exception(
+            "Failed to parse SPARQL XML Query Results format"
+        );
+    }
+
+    /** Parse a SPARQL result in the JSON format into the object.
+     *
+     * @ignore
+     */
+    protected function parseJson($data)
+    {
+        // Decode JSON to an array
+        $data = json_decode($data, true);
+
+        if (isset($data['boolean'])) {
+            $this->type = 'boolean';
+            $this->boolean = $data['boolean'];
+        } elseif (isset($data['results'])) {
+            $this->type = 'bindings';
+            if (isset($data['head']['vars'])) {
+                $this->fields = $data['head']['vars'];
+            }
+
+            foreach ($data['results']['bindings'] as $row) {
+                $t = new stdClass();
+                foreach ($row as $key => $value) {
+                    $t->$key = $this->newTerm($value);
+                }
+                $this[] = $t;
+            }
+        } else {
+            throw new EasyRdf_Exception(
+                "Failed to parse SPARQL JSON Query Results format"
+            );
+        }
+    }
+
+    /** Magic method to return value of the result to string
+     *
+     * If this is a boolean result then it will return 'true' or 'false'.
+     * If it is a bindings type, then it will dump as a text based table.
+     *
+     * @return string A string representation of the result.
+     */
+    public function __toString()
+    {
+        if ($this->type == 'boolean') {
+            return $this->boolean ? 'true' : 'false';
+        } else {
+            return $this->dump('text');
+        }
+    }
+}