Minor dependency updates
[yaffs-website] / vendor / easyrdf / easyrdf / lib / EasyRdf / Parser / Redland.php
1 <?php
2
3 /**
4  * EasyRdf
5  *
6  * LICENSE
7  *
8  * Copyright (c) 2009-2013 Nicholas J Humfrey.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  *    this list of conditions and the following disclaimer in the documentation
16  *    and/or other materials provided with the distribution.
17  * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
18  *    promote products derived from this software without specific prior
19  *    written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * @package    EasyRdf
34  * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
35  * @license    http://www.opensource.org/licenses/bsd-license.php
36  */
37
38 /**
39  * Class to parse RDF using Redland (librdf) C library.
40  *
41  * @package    EasyRdf
42  * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
43  * @license    http://www.opensource.org/licenses/bsd-license.php
44  */
45 class EasyRdf_Parser_Redland extends EasyRdf_Parser
46 {
47     /** Variable set to the librdf world */
48     private $world = null;
49
50     /** Parser feature URI string for getting the error count of last parse. */
51     const LIBRDF_PARSER_FEATURE_ERROR_COUNT =
52         'http://feature.librdf.org/parser-error-count';
53
54     /*
55      *  Types supported by Redland:
56      *
57      *  ntriples: N-Triples
58      *  turtle: Turtle Terse RDF Triple Language
59      *  trig: TriG - Turtle with Named Graphs
60      *  rss-tag-soup: RSS Tag Soup
61      *  grddl: Gleaning Resource Descriptions from Dialects of Languages
62      *  guess: Pick the parser to use using content type and URI
63      *  rdfa: RDF/A via librdfa
64      *  raptor: (null)
65      *  rdfxml: RDF/XML
66      */
67
68
69     /**
70      * Convert a librdf node type into a string
71      * @ignore
72      */
73     protected function nodeTypeString($node)
74     {
75         switch(librdf_node_get_type($node)) {
76             case 1:
77                 return 'uri';
78                 break;
79             case 2:
80                 return 'literal';
81                 break;
82             case 4:
83                 return 'bnode';
84                 break;
85             default:
86                 return 'unknown';
87                 break;
88         }
89     }
90
91     /**
92      * Convert the URI for a node into a string
93      * @ignore
94      */
95     protected function nodeUriString($node)
96     {
97         $type = EasyRdf_Parser_Redland::nodeTypeString($node);
98         if ($type == 'uri') {
99             $uri = librdf_node_get_uri($node);
100             if (!$uri) {
101                 throw new EasyRdf_Exception("Failed to get URI of node");
102             }
103             $str = librdf_uri_to_string($uri);
104             if (!$str) {
105                 throw new EasyRdf_Exception(
106                     "Failed to convert librdf_uri to string"
107                 );
108             }
109             return $str;
110         } elseif ($type == 'bnode') {
111             return $this->remapBnode(
112                 librdf_node_get_blank_identifier($node)
113             );
114         } else {
115             throw new EasyRdf_Exception("Unsupported type: ".$type);
116         }
117     }
118
119     /**
120      * Convert a node into an associate array
121      * @ignore
122      */
123     protected function nodeToRdfPhp($node)
124     {
125         $object = array();
126         $object['type'] = EasyRdf_Parser_Redland::nodeTypeString($node);
127         if ($object['type'] == 'uri') {
128             $object['value'] = EasyRdf_Parser_Redland::nodeUriString($node);
129         } elseif ($object['type'] == 'bnode') {
130             $object['value'] = '_:'.librdf_node_get_blank_identifier($node);
131         } elseif ($object['type'] == 'literal') {
132             $object['value'] = librdf_node_get_literal_value($node);
133             $lang = librdf_node_get_literal_value_language($node);
134             if ($lang) {
135                 $object['lang'] = $lang;
136             }
137             $datatype = librdf_node_get_literal_value_datatype_uri($node);
138             if ($datatype) {
139                 $object['datatype'] = librdf_uri_to_string($datatype);
140             }
141         } else {
142             throw new EasyRdf_Exception("Unsupported type: ".$object['type']);
143         }
144         return $object;
145     }
146
147     /**
148      * Return the number of errors during parsing
149      * @ignore
150      */
151     protected function parserErrorCount($parser)
152     {
153         $errorUri = librdf_new_uri(
154             $this->world,
155             self::LIBRDF_PARSER_FEATURE_ERROR_COUNT
156         );
157         $errorNode = librdf_parser_get_feature($parser, $errorUri);
158         $errorCount = librdf_node_get_literal_value($errorNode);
159         librdf_free_uri($errorUri);
160         return $errorCount;
161     }
162
163     /**
164      * Constructor
165      *
166      * @return object EasyRdf_Parser_Redland
167      */
168     public function __construct()
169     {
170         if (extension_loaded('redland')) {
171             $this->world = librdf_php_get_world();
172             if (!$this->world) {
173                 throw new EasyRdf_Exception(
174                     "Failed to initialise librdf world."
175                 );
176             }
177         } else {
178             throw new EasyRdf_Exception(
179                 "Redland PHP extension is not available."
180             );
181         }
182     }
183
184     /**
185       * Parse an RDF document into an EasyRdf_Graph
186       *
187       * @param object EasyRdf_Graph $graph   the graph to load the data into
188       * @param string               $data    the RDF document data
189       * @param string               $format  the format of the input data
190       * @param string               $baseUri the base URI of the data being parsed
191       * @return integer             The number of triples added to the graph
192       */
193     public function parse($graph, $data, $format, $baseUri)
194     {
195         parent::checkParseParams($graph, $data, $format, $baseUri);
196
197         $parser = librdf_new_parser($this->world, $format, null, null);
198         if (!$parser) {
199             throw new EasyRdf_Exception(
200                 "Failed to create librdf_parser of type: $format"
201             );
202         }
203
204         $rdfUri = librdf_new_uri($this->world, $baseUri);
205         if (!$rdfUri) {
206             throw new EasyRdf_Exception(
207                 "Failed to create librdf_uri from: $baseUri"
208             );
209         }
210
211         $stream = librdf_parser_parse_string_as_stream($parser, $data, $rdfUri);
212         if (!$stream) {
213             throw new EasyRdf_Parser_Exception(
214                 "Failed to parse RDF stream"
215             );
216         }
217
218         do {
219             $statement = librdf_stream_get_object($stream);
220             if ($statement) {
221                 $subject = EasyRdf_Parser_Redland::nodeUriString(
222                     librdf_statement_get_subject($statement)
223                 );
224                 $predicate = EasyRdf_Parser_Redland::nodeUriString(
225                     librdf_statement_get_predicate($statement)
226                 );
227                 $object = EasyRdf_Parser_Redland::nodeToRdfPhp(
228                     librdf_statement_get_object($statement)
229                 );
230
231                 $this->addTriple($subject, $predicate, $object);
232             }
233         } while (!librdf_stream_next($stream));
234
235         $errorCount = $this->parserErrorCount($parser);
236         if ($errorCount) {
237             throw new EasyRdf_Parser_Exception("$errorCount errors while parsing.");
238         }
239
240         librdf_free_uri($rdfUri);
241         librdf_free_stream($stream);
242         librdf_free_parser($parser);
243
244         return $this->tripleCount;
245     }
246 }