From 9ad506423508c44d733ff6a7fcd81e3d267b317d Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Fri, 11 Jan 2013 09:42:26 -0800 Subject: [PATCH] Issue #1866858 by linclark, scor: Test RDFa by parsing RDFa (add the easyrdf library). --- core/composer.json | 3 +- core/composer.lock | 33 + core/vendor/composer/autoload_namespaces.php | 1 + core/vendor/njh/easyrdf/lib/EasyRdf.php | 225 +++ .../njh/easyrdf/lib/EasyRdf/Exception.php | 51 + .../vendor/njh/easyrdf/lib/EasyRdf/Format.php | 679 +++++++ core/vendor/njh/easyrdf/lib/EasyRdf/Graph.php | 1627 +++++++++++++++++ .../njh/easyrdf/lib/EasyRdf/GraphStore.php | 217 +++ core/vendor/njh/easyrdf/lib/EasyRdf/Http.php | 83 + .../njh/easyrdf/lib/EasyRdf/Http/Client.php | 549 ++++++ .../njh/easyrdf/lib/EasyRdf/Http/Response.php | 361 ++++ .../njh/easyrdf/lib/EasyRdf/Literal.php | 315 ++++ .../easyrdf/lib/EasyRdf/Literal/Boolean.php | 96 + .../njh/easyrdf/lib/EasyRdf/Literal/Date.php | 134 ++ .../easyrdf/lib/EasyRdf/Literal/DateTime.php | 114 ++ .../easyrdf/lib/EasyRdf/Literal/Decimal.php | 71 + .../njh/easyrdf/lib/EasyRdf/Literal/HTML.php | 73 + .../easyrdf/lib/EasyRdf/Literal/HexBinary.php | 92 + .../easyrdf/lib/EasyRdf/Literal/Integer.php | 71 + .../njh/easyrdf/lib/EasyRdf/Literal/XML.php | 74 + .../njh/easyrdf/lib/EasyRdf/Namespace.php | 349 ++++ .../njh/easyrdf/lib/EasyRdf/ParsedUri.php | 341 ++++ .../vendor/njh/easyrdf/lib/EasyRdf/Parser.php | 150 ++ .../njh/easyrdf/lib/EasyRdf/Parser/Arc.php | 97 + .../njh/easyrdf/lib/EasyRdf/Parser/Json.php | 156 ++ .../easyrdf/lib/EasyRdf/Parser/Ntriples.php | 199 ++ .../njh/easyrdf/lib/EasyRdf/Parser/Rapper.php | 103 ++ .../njh/easyrdf/lib/EasyRdf/Parser/RdfPhp.php | 100 + .../njh/easyrdf/lib/EasyRdf/Parser/RdfXml.php | 807 ++++++++ .../njh/easyrdf/lib/EasyRdf/Parser/Rdfa.php | 710 +++++++ .../easyrdf/lib/EasyRdf/Parser/Redland.php | 247 +++ .../njh/easyrdf/lib/EasyRdf/Parser/Turtle.php | 1134 ++++++++++++ .../njh/easyrdf/lib/EasyRdf/Resource.php | 692 +++++++ .../njh/easyrdf/lib/EasyRdf/Serialiser.php | 115 ++ .../easyrdf/lib/EasyRdf/Serialiser/Arc.php | 97 + .../lib/EasyRdf/Serialiser/GraphViz.php | 391 ++++ .../easyrdf/lib/EasyRdf/Serialiser/Json.php | 70 + .../lib/EasyRdf/Serialiser/Ntriples.php | 209 +++ .../easyrdf/lib/EasyRdf/Serialiser/Rapper.php | 100 + .../easyrdf/lib/EasyRdf/Serialiser/RdfPhp.php | 71 + .../easyrdf/lib/EasyRdf/Serialiser/RdfXml.php | 218 +++ .../easyrdf/lib/EasyRdf/Serialiser/Turtle.php | 266 +++ .../njh/easyrdf/lib/EasyRdf/Sparql/Client.php | 134 ++ .../njh/easyrdf/lib/EasyRdf/Sparql/Result.php | 381 ++++ .../njh/easyrdf/lib/EasyRdf/TypeMapper.php | 116 ++ core/vendor/njh/easyrdf/lib/EasyRdf/Utils.php | 276 +++ 46 files changed, 12397 insertions(+), 1 deletion(-) create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Exception.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Format.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Graph.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/GraphStore.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Http.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Http/Client.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Http/Response.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Boolean.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Date.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/DateTime.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Decimal.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HTML.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HexBinary.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Integer.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Literal/XML.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Namespace.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/ParsedUri.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Arc.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Json.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Ntriples.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rapper.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfPhp.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfXml.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rdfa.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Redland.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Turtle.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Resource.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Arc.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/GraphViz.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Json.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Ntriples.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Rapper.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfPhp.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfXml.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Turtle.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Client.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Result.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/TypeMapper.php create mode 100644 core/vendor/njh/easyrdf/lib/EasyRdf/Utils.php diff --git a/core/composer.json b/core/composer.json index 26030b061ede..ab2dc0e3a400 100644 --- a/core/composer.json +++ b/core/composer.json @@ -15,7 +15,8 @@ "doctrine/common": "2.3.*@stable", "guzzle/http": "*", "kriswallsmith/assetic": "1.1.*@alpha", - "symfony-cmf/routing": "1.0.*@dev" + "symfony-cmf/routing": "1.0.*@dev", + "njh/easyrdf": "0.8.*" }, "minimum-stability": "dev" } diff --git a/core/composer.lock b/core/composer.lock index 9ca06b566793..07d030c8a3ba 100644 --- a/core/composer.lock +++ b/core/composer.lock @@ -359,6 +359,39 @@ "routing" ] }, + { + "name": "njh/easyrdf", + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "version": "0.8.0", + "type": "library", + "keywords": ["RDF", "Semantic Web", "Turtle", "RDFa"], + "homepage": "http://www.aelius.com/njh/easyrdf/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + } + ], + "support": { + "forum": "http://groups.google.com/group/easyrdf/", + "issues": "http://github.com/njh/easyrdf/issues" + }, + "require": { + "php": ">=5.2.8" + }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/njh/easyrdf" + } + ], + "autoload": { + "psr-0": { "EasyRdf": "lib/" } + } + }, { "name": "symfony/class-loader", "version": "dev-master", diff --git a/core/vendor/composer/autoload_namespaces.php b/core/vendor/composer/autoload_namespaces.php index ecb4b198634e..4fa7f515bd96 100644 --- a/core/vendor/composer/autoload_namespaces.php +++ b/core/vendor/composer/autoload_namespaces.php @@ -23,4 +23,5 @@ 'Guzzle\\Common' => $vendorDir . '/guzzle/common/', 'Doctrine\\Common' => $vendorDir . '/doctrine/common/lib/', 'Assetic' => $vendorDir . '/kriswallsmith/assetic/src/', + 'EasyRdf_' => $vendorDir . '/njh/easyrdf/lib/', ); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf.php b/core/vendor/njh/easyrdf/lib/EasyRdf.php new file mode 100644 index 000000000000..2aaae30d9f78 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf.php @@ -0,0 +1,225 @@ +<?php + +/** + * EasyRdf + * + * Use this file to load the core of EasyRdf, if you don't have an autoloader. + * + * + * LICENSE + * + * Copyright (c) 2009-2011 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) 2011 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * @see EasyRdf_Exception + */ +require_once "EasyRdf/Exception.php"; + +/** + * @see EasyRdf_Format + */ +require_once "EasyRdf/Format.php"; + +/** + * @see EasyRdf_Graph + */ +require_once "EasyRdf/Graph.php"; + +/** + * @see EasyRdf_GraphStore + */ +require_once "EasyRdf/GraphStore.php"; + +/** + * @see EasyRdf_Http + */ +require_once "EasyRdf/Http.php"; + +/** + * @see EasyRdf_Http_Client + */ +require_once "EasyRdf/Http/Client.php"; + +/** + * @see EasyRdf_Http_Response + */ +require_once "EasyRdf/Http/Response.php"; + +/** + * @see EasyRdf_Namespace + */ +require_once "EasyRdf/Namespace.php"; + +/** + * @see EasyRdf_Literal + */ +require_once "EasyRdf/Literal.php"; + +/** + * @see EasyRdf_Literal_Boolean + */ +require_once "EasyRdf/Literal/Boolean.php"; + +/** + * @see EasyRdf_Literal_Date + */ +require_once "EasyRdf/Literal/Date.php"; + +/** + * @see EasyRdf_Literal_DateTime + */ +require_once "EasyRdf/Literal/DateTime.php"; + +/** + * @see EasyRdf_Literal_Decimal + */ +require_once "EasyRdf/Literal/Decimal.php"; + +/** + * @see EasyRdf_Literal_HexBinary + */ +require_once "EasyRdf/Literal/HexBinary.php"; + +/** + * @see EasyRdf_Literal_HTML + */ +require_once "EasyRdf/Literal/HTML.php"; + +/** + * @see EasyRdf_Literal_Integer + */ +require_once "EasyRdf/Literal/Integer.php"; + +/** + * @see EasyRdf_Literal_XML + */ +require_once "EasyRdf/Literal/XML.php"; + +/** + * @see EasyRdf_ParsedUri + */ +require_once "EasyRdf/ParsedUri.php"; + +/** + * @see EasyRdf_Parser + */ +require_once "EasyRdf/Parser.php"; + +/** + * @see EasyRdf_Parser_RdfPhp + */ +require_once "EasyRdf/Parser/RdfPhp.php"; + +/** + * @see EasyRdf_Parser_Ntriples + */ +require_once "EasyRdf/Parser/Ntriples.php"; + +/** + * @see EasyRdf_Parser_Json + */ +require_once "EasyRdf/Parser/Json.php"; + +/** + * @see EasyRdf_Parser_Rdfa + */ +require_once "EasyRdf/Parser/Rdfa.php"; + +/** + * @see EasyRdf_Parser_RdfXml + */ +require_once "EasyRdf/Parser/RdfXml.php"; + +/** + * @see EasyRdf_Parser_Turtle + */ +require_once "EasyRdf/Parser/Turtle.php"; + +/** + * @see EasyRdf_Resource + */ +require_once "EasyRdf/Resource.php"; + +/** + * @see EasyRdf_Serialiser + */ +require_once "EasyRdf/Serialiser.php"; + +/** + * @see EasyRdf_Serialiser_GraphViz + */ +require_once "EasyRdf/Serialiser/GraphViz.php"; + +/** + * @see EasyRdf_Serialiser_RdfPhp + */ +require_once "EasyRdf/Serialiser/RdfPhp.php"; + +/** + * @see EasyRdf_Serialiser_Ntriples + */ +require_once "EasyRdf/Serialiser/Ntriples.php"; + +/** + * @see EasyRdf_Serialiser_Json + */ +require_once "EasyRdf/Serialiser/Json.php"; + +/** + * @see EasyRdf_Serialiser_RdfXml + */ +require_once "EasyRdf/Serialiser/RdfXml.php"; + +/** + * @see EasyRdf_Serialiser_Turtle + */ +require_once "EasyRdf/Serialiser/Turtle.php"; + +/** + * @see EasyRdf_Sparql_Client + */ +require_once "EasyRdf/Sparql/Client.php"; + +/** + * @see EasyRdf_Sparql_Result + */ +require_once "EasyRdf/Sparql/Result.php"; + +/** + * @see EasyRdf_TypeMapper + */ +require_once "EasyRdf/TypeMapper.php"; + +/** + * @see EasyRdf_Utils + */ +require_once "EasyRdf/Utils.php"; diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Exception.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Exception.php new file mode 100644 index 000000000000..71530cac2ce5 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Exception.php @@ -0,0 +1,51 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * EasyRdf Exception class + * + * All exceptions thrown by EasyRdf are an instance of this class. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Exception extends Exception +{ + // Comment to make PHP CodeSniffer happy +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Format.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Format.php new file mode 100644 index 000000000000..f5bbd5a2a403 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Format.php @@ -0,0 +1,679 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class the represents an RDF file format. + * + * For each format, the name, label, URIs and associated MIME Types are + * stored. A single parser and serialiser can also be registered to each + * format. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Format +{ + private static $formats = array(); + + private $name = array(); + private $label = null; + private $uri = null; + private $mimeTypes = array(); + private $extensions = array(); + private $parserClass = null; + private $serialiserClass = null; + + /** Get a list of format names + * + * @return array An array of formats name + */ + public static function getNames() + { + return array_keys(self::$formats); + } + + /** Get a list of all the registered formats + * + * @return array An array of format objects + */ + public static function getFormats() + { + return self::$formats; + } + + /** Generates an HTTP Accept header string + * + * The string will contain all of the MIME Types that we + * are able to parse. + * + * It is also possible to specify additional MIME types + * in the form array('text/plain' => 0.5) where 0.5 is the + * q value for that type. The types are sorted by q value + * before constructing the string. + * + * @param array $extraTypes extra MIME types to add + * @return string list of supported MIME types + */ + public static function getHttpAcceptHeader($extraTypes = array()) + { + $accept = $extraTypes; + foreach (self::$formats as $format) { + if ($format->parserClass and count($format->mimeTypes) > 0) { + $accept = array_merge($accept, $format->mimeTypes); + } + } + arsort($accept, SORT_NUMERIC); + + $acceptStr=''; + foreach ($accept as $type => $q) { + if ($acceptStr) { + $acceptStr .= ','; + } + if ($q == 1.0) { + $acceptStr .= $type; + } else { + $acceptStr .= sprintf("%s;q=%1.1f", $type, $q); + } + } + return $acceptStr; + } + + /** Check if a named graph exists + * + * @param string $name the name of the format + * @return boolean true if the format exists + */ + public static function formatExists($name) + { + return array_key_exists($name, self::$formats); + } + + /** Get a EasyRdf_Format from a name, uri or mime type + * + * @param string $query a query string to search for + * @return object the first EasyRdf_Format that matches the query + * @throws EasyRdf_Exception if no format is found + */ + public static function getFormat($query) + { + if (!is_string($query) or $query == null or $query == '') { + throw new InvalidArgumentException( + "\$query should be a string and cannot be null or empty" + ); + } + + foreach (self::$formats as $format) { + if ($query == $format->name or + $query == $format->uri or + array_key_exists($query, $format->mimeTypes) or + in_array($query, $format->extensions)) { + return $format; + } + } + + # No match + throw new EasyRdf_Exception( + "Format is not recognised: $query" + ); + } + + /** Register a new format + * + * @param string $name The name of the format (e.g. ntriples) + * @param string $label The label for the format (e.g. N-Triples) + * @param string $uri The URI for the format + * @param string $mimeTypes One or more mime types for the format + * @param string $extensions One or more extensions (file suffix) + * @return object The new EasyRdf_Format object + */ + public static function register( + $name, + $label = null, + $uri = null, + $mimeTypes = array(), + $extensions = array() + ) { + if (!is_string($name) or $name == null or $name == '') { + throw new InvalidArgumentException( + "\$name should be a string and cannot be null or empty" + ); + } + + if (!array_key_exists($name, self::$formats)) { + self::$formats[$name] = new EasyRdf_Format($name); + } + + self::$formats[$name]->setLabel($label); + self::$formats[$name]->setUri($uri); + self::$formats[$name]->setMimeTypes($mimeTypes); + self::$formats[$name]->setExtensions($extensions); + return self::$formats[$name]; + } + + /** Remove a format from the registry + * + * @param string $name The name of the format (e.g. ntriples) + */ + public static function unregister($name) + { + unset(self::$formats[$name]); + } + + /** Class method to register a parser class to a format name + * + * @param string $name The name of the format (e.g. ntriples) + * @param string $class The name of the class (e.g. EasyRdf_Parser_Ntriples) + */ + public static function registerParser($name, $class) + { + if (!self::formatExists($name)) { + self::register($name); + } + self::getFormat($name)->setParserClass($class); + } + + /** Class method to register a serialiser class to a format name + * + * @param string $name The name of the format (e.g. ntriples) + * @param string $class The name of the class (e.g. EasyRdf_Serialiser_Ntriples) + */ + public static function registerSerialiser($name, $class) + { + if (!self::formatExists($name)) { + self::register($name); + } + self::getFormat($name)->setSerialiserClass($class); + } + + /** Attempt to guess the document format from some content. + * + * If $filename is given, then the suffix is first used to guess the format. + * + * If the document format is not recognised, null is returned. + * + * @param string $data The document data + * @param string $filename Optional filename + * @return object EasyRdf_Format The format object + */ + public static function guessFormat($data, $filename = null) + { + if (is_array($data)) { + # Data has already been parsed into RDF/PHP + return self::getFormat('php'); + } + + // First try and identify by the filename + if ($filename and preg_match("/\.(\w+)$/", $filename, $matches)) { + foreach (self::$formats as $format) { + if (in_array($matches[1], $format->extensions)) { + return $format; + } + } + } + + // Then try and guess by the first 255 bytes of content + $short = substr($data, 0, 255); + if (preg_match("/^\s*\{/", $short)) { + return self::getFormat('json'); + } elseif (preg_match("/<rdf:/i", $short)) { + return self::getFormat('rdfxml'); + } elseif (preg_match("/@prefix\s|@base\s/", $short)) { + return self::getFormat('turtle'); + } elseif (preg_match("/^\s*<.+> <.+>/m", $short)) { + return self::getFormat('ntriples'); + } elseif (preg_match("|http://www.w3.org/2005/sparql-results|", $short)) { + return self::getFormat('sparql-xml'); + } elseif (preg_match("/\WRDFa\W/i", $short)) { + return self::getFormat('rdfa'); + } elseif (preg_match("/<!DOCTYPE html|<html/i", $short)) { + # We don't support any other microformats embedded in HTML + return self::getFormat('rdfa'); + } else { + return null; + } + } + + /** + * This constructor is for internal use only. + * To create a new format, use the register method. + * + * @param string $name The name of the format + * @see EasyRdf_Format::register() + * @ignore + */ + public function __construct($name) + { + $this->name = $name; + $this->label = $name; # Only a default + } + + /** Get the name of a format object + * + * @return string The name of the format (e.g. rdfxml) + */ + public function getName() + { + return $this->name; + } + + /** Get the label for a format object + * + * @return string The format label (e.g. RDF/XML) + */ + public function getLabel() + { + return $this->label; + } + + /** Set the label for a format object + * + * @param string $label The new label for the format + */ + public function setLabel($label) + { + if ($label) { + if (!is_string($label)) { + throw new InvalidArgumentException( + "\$label should be a string" + ); + } + return $this->label = $label; + } else { + return $this->label = null; + } + } + + /** Get the URI for a format object + * + * @return string The format URI + */ + public function getUri() + { + return $this->uri; + } + + /** Set the URI for a format object + * + * @param string $uri The new URI for the format + */ + public function setUri($uri) + { + if ($uri) { + if (!is_string($uri)) { + throw new InvalidArgumentException( + "\$uri should be a string" + ); + } + return $this->uri = $uri; + } else { + return $this->uri = null; + } + } + + /** Get the default registered mime type for a format object + * + * @return string The default mime type as a string. + */ + public function getDefaultMimeType() + { + $types = array_keys($this->mimeTypes); + return $types[0]; + } + + /** Get all the registered mime types for a format object + * + * @return array One or more MIME types in an array with + * the mime type as the key and q value as the value + */ + public function getMimeTypes() + { + return $this->mimeTypes; + } + + /** Set the MIME Types for a format object + * + * @param array $mimeTypes One or more mime types + */ + public function setMimeTypes($mimeTypes) + { + if ($mimeTypes) { + if (!is_array($mimeTypes)) { + $mimeTypes = array($mimeTypes); + } + $this->mimeTypes = $mimeTypes; + } else { + $this->mimeTypes = array(); + } + } + + /** Get the default registered file extension (filename suffix) for a format object + * + * @return string The default extension as a string. + */ + public function getDefaultExtension() + { + return $this->extensions[0]; + } + + /** Get all the registered file extensions (filename suffix) for a format object + * + * @return array One or more extensions as an array + */ + public function getExtensions() + { + return $this->extensions; + } + + /** Set the file format extensions (filename suffix) for a format object + * + * @param mixed $extensions One or more file extensions + */ + public function setExtensions($extensions) + { + if ($extensions) { + if (!is_array($extensions)) { + $extensions = array($extensions); + } + $this->extensions = $extensions; + } else { + $this->extensions = array(); + } + } + + /** Set the parser to use for a format + * + * @param string $class The name of the class + */ + public function setParserClass($class) + { + if ($class) { + if (!is_string($class)) { + throw new InvalidArgumentException( + "\$class should be a string" + ); + } + $this->parserClass = $class; + } else { + $this->parserClass = null; + } + } + + /** Get the name of the class to use to parse the format + * + * @return string The name of the class + */ + public function getParserClass() + { + return $this->parserClass; + } + + /** Create a new parser to parse this format + * + * @return object The new parser object + */ + public function newParser() + { + $parserClass = $this->parserClass; + if (!$parserClass) { + throw new EasyRdf_Exception( + "No parser class available for format: ".$this->getName() + ); + } + return (new $parserClass()); + } + + /** Set the serialiser to use for a format + * + * @param string $class The name of the class + */ + public function setSerialiserClass($class) + { + if ($class) { + if (!is_string($class)) { + throw new InvalidArgumentException( + "\$class should be a string" + ); + } + $this->serialiserClass = $class; + } else { + $this->serialiserClass = null; + } + } + + /** Get the name of the class to use to serialise the format + * + * @return string The name of the class + */ + public function getSerialiserClass() + { + return $this->serialiserClass; + } + + /** Create a new serialiser to parse this format + * + * @return object The new serialiser object + */ + public function newSerialiser() + { + $serialiserClass = $this->serialiserClass; + if (!$serialiserClass) { + throw new EasyRdf_Exception( + "No serialiser class available for format: ".$this->getName() + ); + } + return (new $serialiserClass()); + } + + /** Magic method to return the name of the format when casted to string + * + * @return string The name of the format + */ + public function __toString() + { + return $this->name; + } +} + + +/* + Register default set of supported formats + NOTE: they are ordered by preference +*/ + +EasyRdf_Format::register( + 'php', + 'RDF/PHP', + 'http://n2.talis.com/wiki/RDF_PHP_Specification' +); + +EasyRdf_Format::register( + 'json', + 'RDF/JSON Resource-Centric', + 'http://n2.talis.com/wiki/RDF_JSON_Specification', + array( + 'application/json' => 1.0, + 'text/json' => 0.9, + 'application/rdf+json' => 0.9 + ), + array('json') +); + +EasyRdf_Format::register( + 'ntriples', + 'N-Triples', + 'http://www.w3.org/TR/rdf-testcases/#ntriples', + array( + 'text/plain' => 1.0, + 'text/ntriples' => 0.9, + 'application/ntriples' => 0.9, + 'application/x-ntriples' => 0.9 + ), + array('nt') +); + +EasyRdf_Format::register( + 'turtle', + 'Turtle Terse RDF Triple Language', + 'http://www.dajobe.org/2004/01/turtle', + array( + 'text/turtle' => 0.8, + 'application/turtle' => 0.7, + 'application/x-turtle' => 0.7 + ), + array('ttl') +); + +EasyRdf_Format::register( + 'rdfxml', + 'RDF/XML', + 'http://www.w3.org/TR/rdf-syntax-grammar', + array( + 'application/rdf+xml' => 0.8 + ), + array('rdf', 'xrdf') +); + +EasyRdf_Format::register( + 'dot', + 'Graphviz', + 'http://www.graphviz.org/doc/info/lang.html', + array( + 'text/vnd.graphviz' => 0.8 + ), + array('gv', 'dot') +); + +EasyRdf_Format::register( + 'json-triples', + 'RDF/JSON Triples' +); + +EasyRdf_Format::register( + 'n3', + 'Notation3', + 'http://www.w3.org/2000/10/swap/grammar/n3#', + array( + 'text/n3' => 0.5, + 'text/rdf+n3' => 0.5 + ), + array('n3') +); + +EasyRdf_Format::register( + 'rdfa', + 'RDFa', + 'http://www.w3.org/TR/rdfa-core/', + array( + 'text/html' => 0.4, + 'application/xhtml+xml' => 0.4 + ), + array('html') +); + +EasyRdf_Format::register( + 'sparql-xml', + 'SPARQL XML Query Results', + 'http://www.w3.org/TR/rdf-sparql-XMLres/', + array( + 'application/sparql-results+xml' => 1.0 + ) +); + +EasyRdf_Format::register( + 'sparql-json', + 'SPARQL JSON Query Results', + 'http://www.w3.org/TR/rdf-sparql-json-res/', + array( + 'application/sparql-results+json' => 1.0 + ) +); + +EasyRdf_Format::register( + 'png', + 'Portable Network Graphics (PNG)', + 'http://www.w3.org/TR/PNG/', + array( + 'image/png' => 0.3 + ), + array('png') +); + +EasyRdf_Format::register( + 'gif', + 'Graphics Interchange Format (GIF)', + 'http://www.w3.org/Graphics/GIF/spec-gif89a.txt', + array( + 'image/gif' => 0.2 + ), + array('gif') +); + +EasyRdf_Format::register( + 'svg', + 'Scalable Vector Graphics (SVG)', + 'http://www.w3.org/TR/SVG/', + array( + 'image/svg+xml' => 0.3 + ), + array('svg') +); + + +/* + Register default set of parsers and serialisers +*/ + +EasyRdf_Format::registerParser('json', 'EasyRdf_Parser_Json'); +EasyRdf_Format::registerParser('ntriples', 'EasyRdf_Parser_Ntriples'); +EasyRdf_Format::registerParser('php', 'EasyRdf_Parser_RdfPhp'); +EasyRdf_Format::registerParser('rdfxml', 'EasyRdf_Parser_RdfXml'); +EasyRdf_Format::registerParser('turtle', 'EasyRdf_Parser_Turtle'); +EasyRdf_Format::registerParser('rdfa', 'EasyRdf_Parser_Rdfa'); + +EasyRdf_Format::registerSerialiser('json', 'EasyRdf_Serialiser_Json'); +EasyRdf_Format::registerSerialiser('n3', 'EasyRdf_Serialiser_Turtle'); +EasyRdf_Format::registerSerialiser('ntriples', 'EasyRdf_Serialiser_Ntriples'); +EasyRdf_Format::registerSerialiser('php', 'EasyRdf_Serialiser_RdfPhp'); +EasyRdf_Format::registerSerialiser('rdfxml', 'EasyRdf_Serialiser_RdfXml'); +EasyRdf_Format::registerSerialiser('turtle', 'EasyRdf_Serialiser_Turtle'); + +EasyRdf_Format::registerSerialiser('dot', 'EasyRdf_Serialiser_GraphViz'); +EasyRdf_Format::registerSerialiser('gif', 'EasyRdf_Serialiser_GraphViz'); +EasyRdf_Format::registerSerialiser('png', 'EasyRdf_Serialiser_GraphViz'); +EasyRdf_Format::registerSerialiser('svg', 'EasyRdf_Serialiser_GraphViz'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Graph.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Graph.php new file mode 100644 index 000000000000..5bb3ab123fb1 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Graph.php @@ -0,0 +1,1627 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Container for collection of EasyRdf_Resources. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Graph +{ + /** The URI of the graph */ + private $uri = null; + private $parsedUri = null; + + /** Array of resources contained in the graph */ + private $resources = array(); + + private $index = array(); + private $revIndex = array(); + + /** Counter for the number of bnodes */ + private $bNodeCount = 0; + + /** Array of URLs that have been loaded into the graph */ + private $loaded = array(); + + private $maxRedirects = 10; + + + /** + * Constructor + * + * If no URI is given then an unnamed graph is created. + * + * The $data parameter is optional and will be parsed into + * the graph if given. + * + * The data format is optional and should be specified if it + * can't be guessed by EasyRdf. + * + * @param string $uri The URI of the graph + * @param string $data Data for the graph + * @param string $format The document type of the data (e.g. rdfxml) + * @return object EasyRdf_Graph + */ + public function __construct($uri = null, $data = null, $format = null) + { + $this->checkResourceParam($uri, true); + + if ($uri) { + $this->uri = $uri; + $this->parsedUri = new EasyRdf_ParsedUri($uri); + if ($data) { + $this->parse($data, $format, $this->uri); + } + } + } + + /** + * Create a new graph and load RDF data from a URI into it + * + * This static function is shorthand for: + * $graph = new EasyRdf_Graph($uri); + * $graph->load($uri, $format); + * + * The document type is optional but should be specified if it + * can't be guessed or got from the HTTP headers. + * + * @param string $uri The URI of the data to load + * @param string $format Optional format of the data (eg. rdfxml) + * @return object EasyRdf_Graph The new the graph object + */ + public static function newAndLoad($uri, $format = null) + { + $graph = new self($uri); + $graph->load($uri, $format); + return $graph; + } + + /** Get or create a resource stored in a graph + * + * If the resource did not previously exist, then a new resource will + * be created. If you provide an RDF type and that type is registered + * with the EasyRdf_TypeMapper, then the resource will be an instance + * of the class registered. + * + * If URI is null, then the URI of the graph is used. + * + * @param string $uri The URI of the resource + * @param mixed $types RDF type of a new resource (e.g. foaf:Person) + * @return object EasyRdf_Resource + */ + public function resource($uri = null, $types = array()) + { + $this->checkResourceParam($uri, true); + if (!$uri) { + throw new InvalidArgumentException( + '$uri is null and EasyRdf_Graph object has no URI either.' + ); + } + + // Resolve relative URIs + if ($this->parsedUri) { + $uri = $this->parsedUri->resolve($uri)->toString(); + } + + // Add the types + $this->addType($uri, $types); + + // Create resource object if it doesn't already exist + if (!isset($this->resources[$uri])) { + $resClass = $this->classForResource($uri); + $this->resources[$uri] = new $resClass($uri, $this); + } + + return $this->resources[$uri]; + } + + /** Work out the class to instantiate a resource as + * @ignore + */ + protected function classForResource($uri) + { + $resClass = 'EasyRdf_Resource'; + $rdfType = EasyRdf_Namespace::expand('rdf:type'); + if (isset($this->index[$uri][$rdfType])) { + foreach ($this->index[$uri][$rdfType] as $type) { + if ($type['type'] == 'uri' or $type['type'] == 'bnode') { + $class = EasyRdf_TypeMapper::get($type['value']); + if ($class != null) { + $resClass = $class; + break; + } + } + + } + } + return $resClass; + } + + /** + * Create a new blank node in the graph and return it. + * + * If you provide an RDF type and that type is registered + * with the EasyRdf_TypeMapper, then the resource will be an instance + * of the class registered. + * + * @param mixed $types RDF type of a new blank node (e.g. foaf:Person) + * @return object EasyRdf_Resource The new blank node + */ + public function newBNode($types = array()) + { + return $this->resource($this->newBNodeId(), $types); + } + + /** + * Create a new unique blank node identifier and return it. + * + * @return string The new blank node identifier (e.g. _:genid1) + */ + public function newBNodeId() + { + return "_:genid".(++$this->bNodeCount); + } + + /** + * Parse some RDF data into the graph object. + * + * @param string $data Data to parse for the graph + * @param string $format Optional format of the data + * @param string $uri The URI of the data to load + * @return integer The number of triples added to the graph + */ + public function parse($data, $format = null, $uri = null) + { + $this->checkResourceParam($uri, true); + + if (empty($format) or $format == 'guess') { + // Guess the format if it is Unknown + $format = EasyRdf_Format::guessFormat($data, $uri); + } else { + $format = EasyRdf_Format::getFormat($format); + } + + if (!$format) { + throw new EasyRdf_Exception( + "Unable to parse data of an unknown format." + ); + } + + $parser = $format->newParser(); + return $parser->parse($this, $data, $format, $uri); + } + + /** + * Parse a file containing RDF data into the graph object. + * + * @param string $filename The path of the file to load + * @param string $format Optional format of the file + * @param string $uri The URI of the file to load + * @return integer The number of triples added to the graph + */ + public function parseFile($filename, $format = null, $uri = null) + { + if ($uri === null) { + $uri = "file://$filename"; + } + + return $this->parse( + file_get_contents($filename), + $format, + $uri + ); + } + + /** + * Load RDF data into the graph from a URI. + * + * If no URI is given, then the URI of the graph will be used. + * + * The document type is optional but should be specified if it + * can't be guessed or got from the HTTP headers. + * + * @param string $uri The URI of the data to load + * @param string $format Optional format of the data (eg. rdfxml) + * @return integer The number of triples added to the graph + */ + public function load($uri = null, $format = null) + { + $this->checkResourceParam($uri, true); + + if (!$uri) { + throw new EasyRdf_Exception( + "No URI given to load() and the graph does not have a URI." + ); + } + + // Setup the HTTP client + $client = EasyRdf_Http::getDefaultHttpClient(); + $client->resetParameters(true); + $client->setConfig(array('maxredirects' => 0)); + $client->setMethod('GET'); + $client->setHeaders('Accept', EasyRdf_Format::getHttpAcceptHeader()); + + $requestUrl = $uri; + $response = null; + $redirectCounter = 0; + do { + // Have we already loaded it into the graph? + $requestUrl = EasyRdf_Utils::removeFragmentFromUri($requestUrl); + if (in_array($requestUrl, $this->loaded)) { + return 0; + } + + // Make the HTTP request + $client->setHeaders('host', null); + $client->setUri($requestUrl); + $response = $client->request(); + + // Add the URL to the list of URLs loaded + $this->loaded[] = $requestUrl; + + if ($response->isRedirect() and $location = $response->getHeader('location')) { + // Avoid problems with buggy servers that add whitespace + $location = trim($location); + + // Some servers return relative URLs in the location header + // resolve it in relation to previous request + $baseUri = new EasyRdf_ParsedUri($requestUrl); + $requestUrl = $baseUri->resolve($location)->toString(); + $requestUrl = EasyRdf_Utils::removeFragmentFromUri($requestUrl); + + // If it is a 303 then drop the parameters + if ($response->getStatus() == 303) { + $client->resetParameters(); + } + + ++$redirectCounter; + } elseif ($response->isSuccessful()) { + // If we didn't get any location, stop redirecting + break; + } else { + throw new EasyRdf_Exception( + "HTTP request for $requestUrl failed: ".$response->getMessage() + ); + } + } while ($redirectCounter < $this->maxRedirects); + + if (!$format or $format == 'guess') { + list($format, $params) = EasyRdf_Utils::parseMimeType( + $response->getHeader('Content-Type') + ); + } + + // Parse the data + return $this->parse($response->getBody(), $format, $uri); + } + + /** Get an associative array of all the resources stored in the graph. + * The keys of the array is the URI of the EasyRdf_Resource. + * + * @return array Array of EasyRdf_Resource + */ + public function resources() + { + foreach ($this->index as $subject => $properties) { + $this->resource($subject); + } + + foreach ($this->revIndex as $object => $properties) { + if (!isset($this->resources[$object])) { + $this->resource($object); + } + } + + return $this->resources; + } + + /** Get an arry of resources matching a certain property and optional value. + * + * For example this routine could be used as a way of getting + * everyone who has name: + * $people = $graph->resourcesMatching('foaf:name') + * + * Or everyone who is male: + * $people = $graph->resourcesMatching('foaf:gender', 'male'); + * + * Or all homepages: + * $people = $graph->resourcesMatching('^foaf:homepage'); + * + * @param string $property The property to check. + * @param mixed $value Optional, the value of the propery to check for. + * @return array Array of EasyRdf_Resource + */ + public function resourcesMatching($property, $value = null) + { + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + // Use the reverse index if it is an inverse property + if ($inverse) { + $index = &$this->revIndex; + } else { + $index = &$this->index; + } + + $matched = array(); + foreach ($index as $subject => $props) { + if (isset($index[$subject][$property])) { + if (isset($value)) { + foreach ($this->index[$subject][$property] as $v) { + if ($v['type'] == $value['type'] and + $v['value'] == $value['value']) { + $matched[] = $this->resource($subject); + break; + } + } + } else { + $matched[] = $this->resource($subject); + } + } + } + return $matched; + } + + /** Get the URI of the graph + * + * @return string The URI of the graph + */ + public function getUri() + { + return $this->uri; + } + + /** Check that a URI/resource parameter is valid, and convert it to a string + * @ignore + */ + protected function checkResourceParam(&$resource, $allowNull = false) + { + if ($allowNull == true) { + if ($resource === null) { + if ($this->uri) { + $resource = $this->uri; + } else { + return; + } + } + } elseif ($resource === null) { + throw new InvalidArgumentException( + "\$resource cannot be null" + ); + } + + if (is_object($resource) and $resource instanceof EasyRdf_Resource) { + $resource = $resource->getUri(); + } elseif (is_object($resource) and $resource instanceof EasyRdf_ParsedUri) { + $resource = strval($resource); + } elseif (is_string($resource)) { + if ($resource == '') { + throw new InvalidArgumentException( + "\$resource cannot be an empty string" + ); + } elseif (preg_match("|^<(.+)>$|", $resource, $matches)) { + $resource = $matches[1]; + } else { + $resource = EasyRdf_Namespace::expand($resource); + } + } else { + throw new InvalidArgumentException( + "\$resource should be a string or an EasyRdf_Resource" + ); + } + } + + /** Check that a single URI/property parameter (not a property path) + * is valid, and expand it if required + * @ignore + */ + protected function checkSinglePropertyParam(&$property, &$inverse) + { + if (is_object($property) and $property instanceof EasyRdf_Resource) { + $property = $property->getUri(); + } elseif (is_object($property) and $property instanceof EasyRdf_ParsedUri) { + $property = strval($property); + } elseif (is_string($property)) { + if ($property == '') { + throw new InvalidArgumentException( + "\$property cannot be an empty string" + ); + } elseif (substr($property, 0, 1) == '^') { + $inverse = true; + $property = EasyRdf_Namespace::expand(substr($property, 1)); + } elseif (substr($property, 0, 2) == '_:') { + throw new InvalidArgumentException( + "\$property cannot be a blank node" + ); + } else { + $inverse = false; + $property = EasyRdf_Namespace::expand($property); + } + } + + if ($property === null or !is_string($property)) { + throw new InvalidArgumentException( + "\$property should be a string or EasyRdf_Resource and cannot be null" + ); + } + } + + /** Check that a value parameter is valid, and convert it to an associative array if needed + * @ignore + */ + protected function checkValueParam(&$value) + { + if (isset($value)) { + if (is_object($value)) { + if (method_exists($value, 'toArray')) { + $value = $value->toArray(); + } else { + throw new InvalidArgumentException( + "\$value should respond to the method toArray()" + ); + } + } elseif (is_array($value)) { + if (!isset($value['type'])) { + throw new InvalidArgumentException( + "\$value is missing a 'type' key" + ); + } + + if (!isset($value['value'])) { + throw new InvalidArgumentException( + "\$value is missing a 'value' key" + ); + } + + // Fix ordering and remove unknown keys + $value = array( + 'type' => strval($value['type']), + 'value' => strval($value['value']), + 'lang' => isset($value['lang']) ? strval($value['lang']) : null, + 'datatype' => isset($value['datatype']) ? strval($value['datatype']) : null + ); + } else { + $value = array( + 'type' => 'literal', + 'value' => strval($value), + 'datatype' => EasyRdf_Literal::getDatatypeForValue($value) + ); + } + if (!in_array($value['type'], array('uri', 'bnode', 'literal'), true)) { + throw new InvalidArgumentException( + "\$value does not have a valid type (".$value['type'].")" + ); + } + if (empty($value['datatype'])) { + unset($value['datatype']); + } + if (empty($value['lang'])) { + unset($value['lang']); + } + if (isset($value['lang']) and isset($value['datatype'])) { + throw new InvalidArgumentException( + "\$value cannot have both and language and a datatype" + ); + } + } + } + + /** Get a single value for a property of a resource + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * If $property is an array, then the first item in the array that matches + * a property that exists is returned. + * + * This method will return null if the property does not exist. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $propertyPath A valid property path + * @param string $type The type of value to filter by (e.g. literal or resource) + * @param string $lang The language to filter by (e.g. en) + * @return mixed A value associated with the property + */ + public function get($resource, $propertyPath, $type = null, $lang = null) + { + $this->checkResourceParam($resource); + + if (is_object($propertyPath) and $propertyPath instanceof EasyRdf_Resource) { + return $this->getSingleProperty($resource, $propertyPath->getUri(), $type, $lang); + } elseif (is_string($propertyPath) and preg_match('|^(\^?)<(.+)>|', $propertyPath, $matches)) { + return $this->getSingleProperty($resource, "$matches[1]$matches[2]", $type, $lang); + } elseif ($propertyPath === null or !is_string($propertyPath)) { + throw new InvalidArgumentException( + "\$propertyPath should be a string or EasyRdf_Resource and cannot be null" + ); + } elseif ($propertyPath === '') { + throw new InvalidArgumentException( + "\$propertyPath cannot be an empty string" + ); + } + + // Loop through each component in the path + foreach (explode('/', $propertyPath) as $part) { + // Stop if we come to a literal + if ($resource instanceof EasyRdf_Literal) { + return null; + } + + // Try each of the alternative paths + foreach (explode('|', $part) as $p) { + $res = $this->getSingleProperty($resource, $p, $type, $lang); + if ($res) { + break; + } + } + + // Stop if nothing was found + $resource = $res; + if (!$resource) { + break; + } + } + + return $resource; + } + + /** Get a single value for a property of a resource + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal or resource) + * @param string $lang The language to filter by (e.g. en) + * @return mixed A value associated with the property + * + * @ignore + */ + protected function getSingleProperty($resource, $property, $type = null, $lang = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + + // Get an array of values for the property + $values = $this->propertyValuesArray($resource, $property, $inverse); + if (!isset($values)) { + return null; + } + + // Filter the results + $result = null; + if ($type) { + foreach ($values as $value) { + if ($type == 'literal' and $value['type'] == 'literal') { + if ($lang == null or (isset($value['lang']) and $value['lang'] == $lang)) { + $result = $value; + break; + } + } elseif ($type == 'resource') { + if ($value['type'] == 'uri' or $value['type'] == 'bnode') { + $result = $value; + break; + } + } + } + } else { + $result = $values[0]; + } + + // Convert the internal data structure into a PHP object + return $this->arrayToObject($result); + } + + /** Get a single literal value for a property of a resource + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * This method will return null if there is not literal value for the + * property. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string|array $property The name of the property (e.g. foaf:name) + * @param string $lang The language to filter by (e.g. en) + * @return object EasyRdf_Literal Literal value associated with the property + */ + public function getLiteral($resource, $property, $lang = null) + { + return $this->get($resource, $property, 'literal', $lang); + } + + /** Get a single resource value for a property of a resource + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * This method will return null if there is not resource for the + * property. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string|array $property The name of the property (e.g. foaf:name) + * @return object EasyRdf_Resource Resource associated with the property + */ + public function getResource($resource, $property) + { + return $this->get($resource, $property, 'resource'); + } + + /** Return all the values for a particular property of a resource + * @ignore + */ + protected function propertyValuesArray($resource, $property, $inverse = false) + { + // Is an inverse property being requested? + if ($inverse) { + if (isset($this->revIndex[$resource])) { + $properties = &$this->revIndex[$resource]; + } + } else { + if (isset($this->index[$resource])) { + $properties = &$this->index[$resource]; + } + } + + if (isset($properties[$property])) { + return $properties[$property]; + } else { + return null; + } + } + + /** Get an EasyRdf_Resource or EasyRdf_Literal object from an associative array. + * @ignore + */ + protected function arrayToObject($data) + { + if ($data) { + if ($data['type'] == 'uri' or $data['type'] == 'bnode') { + return $this->resource($data['value']); + } else { + return EasyRdf_Literal::create($data); + } + } else { + return null; + } + } + + /** Get all values for a property path + * + * This method will return an empty array if the property does not exist. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $propertyPath A valid property path + * @param string $type The type of value to filter by (e.g. literal) + * @param string $lang The language to filter by (e.g. en) + * @return array An array of values associated with the property + */ + public function all($resource, $propertyPath, $type = null, $lang = null) + { + $this->checkResourceParam($resource); + + if (is_object($propertyPath) and $propertyPath instanceof EasyRdf_Resource) { + return $this->allForSingleProperty($resource, $propertyPath->getUri(), $type, $lang); + } elseif (is_string($propertyPath) and preg_match('|^(\^?)<(.+)>|', $propertyPath, $matches)) { + return $this->allForSingleProperty($resource, "$matches[1]$matches[2]", $type, $lang); + } elseif ($propertyPath === null or !is_string($propertyPath)) { + throw new InvalidArgumentException( + "\$propertyPath should be a string or EasyRdf_Resource and cannot be null" + ); + } elseif ($propertyPath === '') { + throw new InvalidArgumentException( + "\$propertyPath cannot be an empty string" + ); + } + + $objects = array($resource); + + // Loop through each component in the path + foreach (explode('/', $propertyPath) as $part) { + + $results = array(); + foreach (explode('|', $part) as $p) { + foreach ($objects as $o) { + // Ignore literals found earlier in path + if ($o instanceof EasyRdf_Literal) { + continue; + } + + $results = array_merge( + $results, + $this->allForSingleProperty($o, $p, $type, $lang) + ); + } + } + + // Stop if we don't have anything + if (empty($objects)) { + break; + } + + // Use the results as the input to the next iteration + $objects = $results; + } + + return $objects; + } + + /** Get all values for a single property of a resource + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal) + * @param string $lang The language to filter by (e.g. en) + * @return array An array of values associated with the property + * + * @ignore + */ + protected function allForSingleProperty($resource, $property, $type = null, $lang = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + + // Get an array of values for the property + $values = $this->propertyValuesArray($resource, $property, $inverse); + if (!isset($values)) { + return array(); + } + + $objects = array(); + if ($type) { + foreach ($values as $value) { + if ($type == 'literal' and $value['type'] == 'literal') { + if ($lang == null or (isset($value['lang']) and $value['lang'] == $lang)) { + $objects[] = $this->arrayToObject($value); + } + } elseif ($type == 'resource') { + if ($value['type'] == 'uri' or $value['type'] == 'bnode') { + $objects[] = $this->arrayToObject($value); + } + } + } + } else { + foreach ($values as $value) { + $objects[] = $this->arrayToObject($value); + } + } + return $objects; + } + + /** Get all literal values for a property of a resource + * + * This method will return an empty array if the resource does not + * has any literal values for that property. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $property The name of the property (e.g. foaf:name) + * @param string $lang The language to filter by (e.g. en) + * @return array An array of values associated with the property + */ + public function allLiterals($resource, $property, $lang = null) + { + return $this->all($resource, $property, 'literal', $lang); + } + + /** Get all resources for a property of a resource + * + * This method will return an empty array if the resource does not + * has any resources for that property. + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $property The name of the property (e.g. foaf:name) + * @return array An array of values associated with the property + */ + public function allResources($resource, $property) + { + return $this->all($resource, $property, 'resource'); + } + + /** Get all the resources in the graph of a certain type + * + * If no resources of the type are available and empty + * array is returned. + * + * @param string $type The type of the resource (e.g. foaf:Person) + * @return array The array of resources + */ + public function allOfType($type) + { + return $this->all($type, '^rdf:type'); + } + + /** Count all values for a property of a resource + * + * @param string $resource The URI of the resource (e.g. http://example.com/joe#me) + * @param string $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal) + * @param string $lang The language to filter by (e.g. en) + * @return integer The number of values for this property + */ + public function count($resource, $property, $type = null, $lang = null) + { + return count($this->all($resource, $property, $type, $lang)); + } + + /** Concatenate all values for a property of a resource into a string. + * + * The default is to join the values together with a space character. + * This method will return an empty string if the property does not exist. + * + * @param mixed $resource The resource to get the property on + * @param string $property The name of the property (e.g. foaf:name) + * @param string $glue The string to glue the values together with. + * @param string $lang The language to filter by (e.g. en) + * @return string Concatenation of all the values. + */ + public function join($resource, $property, $glue = ' ', $lang = null) + { + return join($glue, $this->all($resource, $property, 'literal', $lang)); + } + + /** Add data to the graph + * + * The resource can either be a resource or the URI of a resource. + * + * Example: + * $graph->add("http://www.example.com", 'dc:title', 'Title of Page'); + * + * @param mixed $resource The resource to add data to + * @param mixed $property The property name + * @param mixed $value The new value for the property + * @return integer The number of values added (1 or 0) + */ + public function add($resource, $property, $value) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + // No value given? + if ($value === null) { + return 0; + } + + // Check that the value doesn't already exist + if (isset($this->index[$resource][$property])) { + foreach ($this->index[$resource][$property] as $v) { + if ($v == $value) { + return 0; + } + } + } + $this->index[$resource][$property][] = $value; + + // Add to the reverse index if it is a resource + if ($value['type'] == 'uri' or $value['type'] == 'bnode') { + $uri = $value['value']; + $this->revIndex[$uri][$property][] = array( + 'type' => substr($resource, 0, 2) == '_:' ? 'bnode' : 'uri', + 'value' => $resource + ); + } + + // Success + return 1; + } + + /** Add a literal value as a property of a resource + * + * The resource can either be a resource or the URI of a resource. + * The value can either be a single value or an array of values. + * + * Example: + * $graph->add("http://www.example.com", 'dc:title', 'Title of Page'); + * + * @param mixed $resource The resource to add data to + * @param mixed $property The property name + * @param mixed $value The value or values for the property + * @param string $lang The language of the literal + * @return integer The number of values added + */ + public function addLiteral($resource, $property, $value, $lang = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + + if (is_array($value)) { + $added = 0; + foreach ($value as $v) { + $added += $this->addLiteral($resource, $property, $v, $lang); + } + return $added; + } else { + if ($lang) { + $value = array( + 'type' => 'literal', + 'value' => $value, + 'lang' => $lang + ); + } else { + $value = array( + 'type' => 'literal', + 'value' => $value, + 'datatype' => EasyRdf_Literal::getDatatypeForValue($value) + ); + if (empty($value['datatype'])) { + unset($value['datatype']); + } + } + return $this->add($resource, $property, $value); + } + } + + /** Add a resource as a property of another resource + * + * The resource can either be a resource or the URI of a resource. + * + * Example: + * $graph->add("http://example.com/bob", 'foaf:knows', 'http://example.com/alice'); + * + * @param mixed $resource The resource to add data to + * @param mixed $property The property name + * @param mixed $resource2 The resource to be value of the property + * @return integer The number of values added + */ + public function addResource($resource, $property, $resource2) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkResourceParam($resource2); + + return $this->add( + $resource, + $property, + array( + 'type' => substr($resource2, 0, 2) == '_:' ? 'bnode' : 'uri', + 'value' => $resource2 + ) + ); + } + + /** Set a value for a property + * + * The new value will replace the existing values for the property. + * + * @param string $resource The resource to set the property on + * @param string $property The name of the property (e.g. foaf:name) + * @param mixed $value The value for the property + * @return integer The number of values added (1 or 0) + */ + public function set($resource, $property, $value) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + // Delete the old values + $this->delete($resource, $property); + + // Add the new values + return $this->add($resource, $property, $value); + } + + /** Delete a property (or optionally just a specific value) + * + * @param mixed $resource The resource to delete the property from + * @param string $property The name of the property (e.g. foaf:name) + * @param mixed $value The value to delete (null to delete all values) + * @return integer The number of values deleted + */ + public function delete($resource, $property, $value = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + $count = 0; + $property = EasyRdf_Namespace::expand($property); + if (isset($this->index[$resource][$property])) { + foreach ($this->index[$resource][$property] as $k => $v) { + if (!$value or $v == $value) { + unset($this->index[$resource][$property][$k]); + $count++; + if ($v['type'] == 'uri' or $v['type'] == 'bnode') { + $this->deleteInverse($v['value'], $property, $resource); + } + } + } + + // Clean up the indexes - remove empty properties and resources + if ($count) { + if (count($this->index[$resource][$property]) == 0) { + unset($this->index[$resource][$property]); + } + if (count($this->index[$resource]) == 0) { + unset($this->index[$resource]); + } + } + } + + return $count; + } + + /** Delete a resource from a property of another resource + * + * The resource can either be a resource or the URI of a resource. + * + * Example: + * $graph->delete("http://example.com/bob", 'foaf:knows', 'http://example.com/alice'); + * + * @param mixed $resource The resource to delete data from + * @param mixed $property The property name + * @param mixed $resource2 The resource value of the property to be deleted + */ + public function deleteResource($resource, $property, $resource2) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkResourceParam($resource2); + + return $this->delete( + $resource, + $property, + array( + 'type' => substr($resource2, 0, 2) == '_:' ? 'bnode' : 'uri', + 'value' => $resource2 + ) + ); + } + + /** Delete a literal value from a property of a resource + * + * Example: + * $graph->delete("http://www.example.com", 'dc:title', 'Title of Page'); + * + * @param mixed $resource The resource to add data to + * @param mixed $property The property name + * @param mixed $value The value of the property + * @param string $lang The language of the literal + */ + public function deleteLiteral($resource, $property, $value, $lang = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + if ($lang) { + $value['lang'] = $lang; + } + + return $this->delete($resource, $property, $value); + } + + /** This function is for internal use only. + * + * Deletes an inverse property from a resource. + * + * @ignore + */ + protected function deleteInverse($resource, $property, $value) + { + if (isset($this->revIndex[$resource])) { + foreach ($this->revIndex[$resource][$property] as $k => $v) { + if ($v['value'] === $value) { + unset($this->revIndex[$resource][$property][$k]); + } + } + if (count($this->revIndex[$resource][$property]) == 0) { + unset($this->revIndex[$resource][$property]); + } + if (count($this->revIndex[$resource]) == 0) { + unset($this->revIndex[$resource]); + } + } + } + + /** Check if the graph contains any statements + * + * @return boolean True if the graph contains no statements + */ + public function isEmpty() + { + return count($this->index) == 0; + } + + /** Get a list of all the shortened property names (qnames) for a resource. + * + * This method will return an empty array if the resource has no properties. + * + * @return array Array of shortened URIs + */ + public function properties($resource) + { + $this->checkResourceParam($resource); + + $properties = array(); + if (isset($this->index[$resource])) { + foreach ($this->index[$resource] as $property => $value) { + $short = EasyRdf_Namespace::shorten($property); + if ($short) { + $properties[] = $short; + } + } + } + return $properties; + } + + /** Get a list of the full URIs for the properties of a resource. + * + * This method will return an empty array if the resource has no properties. + * + * @return array Array of full URIs + */ + public function propertyUris($resource) + { + $this->checkResourceParam($resource); + + if (isset($this->index[$resource])) { + return array_keys($this->index[$resource]); + } else { + return array(); + } + } + + /** Get a list of the full URIs for the properties that point to a resource. + * + * @return array Array of full property URIs + */ + public function reversePropertyUris($resource) + { + $this->checkResourceParam($resource); + + if (isset($this->revIndex[$resource])) { + return array_keys($this->revIndex[$resource]); + } else { + return array(); + } + } + + /** Check to see if a property exists for a resource. + * + * This method will return true if the property exists. + * If the value parameter is given, then it will only return true + * if the value also exists for that property. + * + * By providing a value parameter you can use this function to check + * to see if a triple exists in the graph. + * + * @param mixed $resource The resource to check + * @param string $property The name of the property (e.g. foaf:name) + * @param mixed $value An optional value of the property + * @return boolean True if value the property exists. + */ + public function hasProperty($resource, $property, $value = null) + { + $this->checkResourceParam($resource); + $this->checkSinglePropertyParam($property, $inverse); + $this->checkValueParam($value); + + // Use the reverse index if it is an inverse property + if ($inverse) { + $index = &$this->revIndex; + } else { + $index = &$this->index; + } + + if (isset($index[$resource][$property])) { + if (is_null($value)) { + return true; + } else { + foreach ($index[$resource][$property] as $v) { + if ($v == $value) { + return true; + } + } + } + } + + return false; + } + + /** Serialise the graph into RDF + * + * The $format parameter can be an EasyRdf_Format object, a + * format name, a mime type or a file extension. + * + * Example: + * $turtle = $graph->serialise('turtle'); + * + * @param mixed $format The format to serialise to + * @return mixed The serialised graph + */ + public function serialise($format) + { + if (!$format instanceof EasyRdf_Format) { + $format = EasyRdf_Format::getFormat($format); + } + $serialiser = $format->newSerialiser(); + return $serialiser->serialise($this, $format->getName()); + } + + /** Return a human readable view of all the resources in the graph + * + * This method is intended to be a debugging aid and will + * return a pretty-print view of all the resources and their + * properties. + * + * @param boolean $html Set to true to format the dump using HTML + * @return string + */ + public function dump($html = true) + { + $result = ''; + if ($html) { + $result .= "<div style='font-family:arial; font-weight: bold; padding:0.5em; ". + "color: black; background-color:lightgrey;border:dashed 1px grey;'>". + "Graph: ". $this->uri . "</div>\n"; + } else { + $result .= "Graph: ". $this->uri . "\n"; + } + + foreach ($this->index as $resource => $properties) { + $result .= $this->dumpResource($resource, $html); + } + return $result; + } + + /** Return a human readable view of a resource and its properties + * + * This method is intended to be a debugging aid and will + * print a resource and its properties. + * + * @param mixed $resource The resource to dump + * @param boolean $html Set to true to format the dump using HTML + * @return string + */ + public function dumpResource($resource, $html = true) + { + $this->checkResourceParam($resource, true); + + if (isset($this->index[$resource])) { + $properties = $this->index[$resource]; + } else { + return ''; + } + + $plist = array(); + foreach ($properties as $property => $values) { + $olist = array(); + foreach ($values as $value) { + if ($value['type'] == 'literal') { + $olist []= EasyRdf_Utils::dumpLiteralValue($value, $html, 'black'); + } else { + $olist []= EasyRdf_Utils::dumpResourceValue($value['value'], $html, 'blue'); + } + } + + $pstr = EasyRdf_Namespace::shorten($property); + if ($pstr == null) { + $pstr = $property; + } + if ($html) { + $plist []= "<span style='font-size:130%'>→</span> ". + "<span style='text-decoration:none;color:green'>". + htmlentities($pstr) . "</span> ". + "<span style='font-size:130%'>→</span> ". + join(", ", $olist); + } else { + $plist []= " -> $pstr -> " . join(", ", $olist); + } + } + + if ($html) { + return "<div id='".htmlentities($resource)."' " . + "style='font-family:arial; padding:0.5em; ". + "background-color:lightgrey;border:dashed 1px grey;'>\n". + "<div>".EasyRdf_Utils::dumpResourceValue($resource, true, 'blue')." ". + "<span style='font-size: 0.8em'>(". + $this->classForResource($resource).")</span></div>\n". + "<div style='padding-left: 3em'>\n". + "<div>".join("</div>\n<div>", $plist)."</div>". + "</div></div>\n"; + } else { + return $resource." (".$this->classForResource($resource).")\n" . + join("\n", $plist) . "\n\n"; + } + } + + /** Get the resource type of the graph + * + * The type will be a shortened URI as a string. + * If the graph has multiple types then the type returned + * may be arbitrary. + * This method will return null if the resource has no type. + * + * @return string A type assocated with the resource (e.g. foaf:Document) + */ + public function type($resource = null) + { + $this->checkResourceParam($resource, true); + + if ($resource) { + $type = $this->get($resource, 'rdf:type', 'resource'); + if ($type) { + return EasyRdf_Namespace::shorten($type); + } + } + + return null; + } + + /** Get the resource type of the graph as a EasyRdf_Resource + * + * If the graph has multiple types then the type returned + * may be arbitrary. + * This method will return null if the resource has no type. + * + * @return object EasyRdf_Resource A type assocated with the resource + */ + public function typeAsResource($resource = null) + { + $this->checkResourceParam($resource, true); + + if ($resource) { + return $this->get($resource, 'rdf:type', 'resource'); + } + + return null; + } + + /** Get a list of types for a resource + * + * The types will each be a shortened URI as a string. + * This method will return an empty array if the resource has no types. + * + * If $resource is null, then it will get the types for the URI of the graph. + * + * @return array All types assocated with the resource (e.g. foaf:Person) + */ + public function types($resource = null) + { + $this->checkResourceParam($resource, true); + + $types = array(); + if ($resource) { + foreach ($this->all($resource, 'rdf:type', 'resource') as $type) { + $types[] = EasyRdf_Namespace::shorten($type); + } + } + + return $types; + } + + /** Check if a resource is of the specified type + * + * @param string $resource The resource to check the type of + * @param string $type The type to check (e.g. foaf:Person) + * @return boolean True if resource is of specified type + */ + public function isA($resource, $type) + { + $this->checkResourceParam($resource, true); + + $type = EasyRdf_Namespace::expand($type); + foreach ($this->all($resource, 'rdf:type', 'resource') as $t) { + if ($t->getUri() == $type) { + return true; + } + } + return false; + } + + /** Add one or more rdf:type properties to a resource + * + * @param string $resource The resource to add the type to + * @param string $types One or more types to add (e.g. foaf:Person) + * @return integer The number of types added + */ + public function addType($resource, $types) + { + $this->checkResourceParam($resource, true); + + if (!is_array($types)) { + $types = array($types); + } + + $count = 0; + foreach ($types as $type) { + $type = EasyRdf_Namespace::expand($type); + $count += $this->add($resource, 'rdf:type', array('type' => 'uri', 'value' => $type)); + } + + return $count; + } + + /** Change the rdf:type property for a resource + * + * Note that if the resource object has already previously + * been created, then the PHP class of the resource will not change. + * + * @param string $resource The resource to change the type of + * @param string $type The new type (e.g. foaf:Person) + * @return integer The number of types added + */ + public function setType($resource, $type) + { + $this->checkResourceParam($resource, true); + + $this->delete($resource, 'rdf:type'); + return $this->addType($resource, $type); + } + + /** Get a human readable label for a resource + * + * This method will check a number of properties for a resource + * (in the order: skos:prefLabel, rdfs:label, foaf:name, dc:title) + * and return an approriate first that is available. If no label + * is available then it will return null. + * + * @return string A label for the resource. + */ + public function label($resource = null, $lang = null) + { + $this->checkResourceParam($resource, true); + + if ($resource) { + return $this->get( + $resource, + 'skos:prefLabel|rdfs:label|foaf:name|dc:title|dc11:title', + 'literal', + $lang + ); + } else { + return null; + } + } + + /** Get the primary topic of the graph + * + * @return EasyRdf_Resource The primary topic of the document. + */ + public function primaryTopic($resource = null) + { + $this->checkResourceParam($resource, true); + + if ($resource) { + return $this->get( + $resource, + 'foaf:primaryTopic|^foaf:isPrimaryTopicOf', + 'resource' + ); + } else { + return null; + } + } + + /** Returns the graph as a RDF/PHP associative array + * + * @return array The contents of the graph as an array. + */ + public function toArray() + { + return $this->index; + } + + /** Calculates the number of triples in the graph + * + * @return integer The number of triples in the graph. + */ + public function countTriples() + { + $count = 0; + foreach ($this->index as $resource) { + foreach ($resource as $property => $values) { + $count += count($values); + } + } + return $count; + } + + /** Magic method to return URI of resource when casted to string + * + * @return string The URI of the resource + */ + public function __toString() + { + return $this->uri == null ? '' : $this->uri; + } + + /** Magic method to get a property of the graph + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * $value = $graph->title; + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + * @return string A single value for the named property + */ + public function __get($name) + { + return $this->get($this->uri, $name); + } + + /** Magic method to set the value for a property of the graph + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * $graph->title = 'Title'; + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + * @param string $value The value for the property + */ + public function __set($name, $value) + { + return $this->set($this->uri, $name, $value); + } + + /** Magic method to check if a property exists + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * if (isset($graph->title)) { blah(); } + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + */ + public function __isset($name) + { + return $this->hasProperty($this->uri, $name); + } + + /** Magic method to delete a property of the graph + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * unset($graph->title); + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + */ + public function __unset($name) + { + return $this->delete($this->uri, $name); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/GraphStore.php b/core/vendor/njh/easyrdf/lib/EasyRdf/GraphStore.php new file mode 100644 index 000000000000..3fcc7b433caf --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/GraphStore.php @@ -0,0 +1,217 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2011 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-2011 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * A class for fetching, saving and deleting graphs to a Graph Store. + * Implementation of the SPARQL 1.1 Graph Store HTTP Protocol. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2011 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_GraphStore +{ + /** The address of the GraphStore endpoint */ + private $uri = null; + private $parsedUri = null; + + + /** Create a new SPARQL Graph Store client + * + * @param string $uri The address of the graph store endpoint + */ + public function __construct($uri) + { + $this->uri = $uri; + $this->parsedUri = new EasyRdf_ParsedUri($uri); + } + + /** Get the URI of the graph store + * + * @return string The URI of the graph store + */ + public function getUri() + { + return $this->uri; + } + + /** Fetch a named graph from the graph store + * + * The URI can either be a full absolute URI or + * a URI relative to the URI of the graph store. + * + * @param string $uriRef The URI of graph desired + * @return object EasyRdf_Graph The graph requested + */ + public function get($uriRef) + { + $graphUri = $this->parsedUri->resolve($uriRef)->toString(); + $dataUrl = $this->urlForGraph($graphUri); + $graph = new EasyRdf_Graph($graphUri); + $graph->load($dataUrl); + return $graph; + } + + /** Send some graph data to the graph store + * + * This method is used by insert() and replace() + * + * @ignore + */ + protected function sendGraph($method, $graph, $uriRef, $format) + { + if (is_object($graph) and $graph instanceof EasyRdf_Graph) { + if ($uriRef == null) { + $uriRef = $graph->getUri(); + } + $data = $graph->serialise($format); + } else { + $data = $graph; + } + + $formatObj = EasyRdf_Format::getFormat($format); + $mimeType = $formatObj->getDefaultMimeType(); + + $graphUri = $this->parsedUri->resolve($uriRef)->toString(); + $dataUrl = $this->urlForGraph($graphUri); + + $client = EasyRdf_Http::getDefaultHttpClient(); + $client->resetParameters(true); + $client->setUri($dataUrl); + $client->setMethod($method); + $client->setRawData($data); + $client->setHeaders('Content-Type', $mimeType); + $client->setHeaders('Content-Length', strlen($data)); + $response = $client->request(); + if (!$response->isSuccessful()) { + throw new EasyRdf_Exception( + "HTTP request for $dataUrl failed: ".$response->getMessage() + ); + } + return $response; + } + + /** Replace the contents of a graph in the graph store with new data + * + * The $graph parameter is the EasyRdf_Graph object to be sent to the + * graph store. Alternatively it can be a string, already serialised. + * + * The URI can either be a full absolute URI or + * a URI relative to the URI of the graph store. + * + * The $format parameter can be given to specify the serialisation + * used to send the graph data to the graph store. + * + * @param object EasyRdfGraph $graph The URI of graph desired + * @param string $uriRef The URI of graph to be replaced + * @param string $format The format of the data to send to the graph store + * @return object EasyRdf_Http_Response The response from the graph store + */ + public function replace($graph, $uriRef = null, $format = 'ntriples') + { + return $this->sendGraph('PUT', $graph, $uriRef, $format); + } + + /** Add data to a graph in the graph store + * + * The $graph parameter is the EasyRdf_Graph object to be sent to the + * graph store. Alternatively it can be a string, already serialised. + * + * The URI can either be a full absolute URI or + * a URI relative to the URI of the graph store. + * + * The $format parameter can be given to specify the serialisation + * used to send the graph data to the graph store. + * + * @param object EasyRdfGraph $graph The URI of graph desired + * @param string $uriRef The URI of graph to be added to + * @param string $format The format of the data to send to the graph store + * @return object EasyRdf_Http_Response The response from the graph store + */ + public function insert($graph, $uriRef = null, $format = 'ntriples') + { + return $this->sendGraph('POST', $graph, $uriRef, $format); + } + + /** Delete a graph from the graph store + * + * The URI can either be a full absolute URI or + * a URI relative to the URI of the graph store. + * + * @param string $uriRef The URI of graph to be added to + * @return object EasyRdf_Http_Response The response from the graph store + */ + public function delete($uriRef) + { + $graphUri = $this->parsedUri->resolve($uriRef)->toString(); + $dataUrl = $this->urlForGraph($graphUri); + + $client = EasyRdf_Http::getDefaultHttpClient(); + $client->resetParameters(true); + $client->setUri($dataUrl); + $client->setMethod('DELETE'); + $response = $client->request(); + if (!$response->isSuccessful()) { + throw new EasyRdf_Exception( + "HTTP request to delete $dataUrl failed: ".$response->getMessage() + ); + } + return $response; + } + + /** Work out the full URL for a graph store request. + * by checking if if it is a direct or indirect request. + * @ignore + */ + protected function urlForGraph($url) + { + if (strpos($url, $this->uri) === false) { + $url = $this->uri."?graph=".urlencode($url); + } + return $url; + } + + /** Magic method to return URI of the graph store when casted to string + * + * @return string The URI of the graph store + */ + public function __toString() + { + return empty($this->uri) ? '' : $this->uri; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Http.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Http.php new file mode 100644 index 000000000000..c8a1d3dbae86 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Http.php @@ -0,0 +1,83 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2011 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-2011 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + + +/** + * Static class to set the HTTP client used by EasyRdf + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2011 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Http +{ + /** The default HTTP Client object */ + private static $defaultHttpClient = null; + + /** Set the HTTP Client object used to fetch RDF data + * + * @param object mixed $httpClient The new HTTP client object + * @return object mixed The new HTTP client object + */ + public static function setDefaultHttpClient($httpClient) + { + if (!is_object($httpClient) or + !($httpClient instanceof Zend_Http_Client or + $httpClient instanceof EasyRdf_Http_Client)) { + throw new InvalidArgumentException( + "\$httpClient should be an object of class Zend_Http_Client or EasyRdf_Http_Client" + ); + } + return self::$defaultHttpClient = $httpClient; + } + + /** Get the HTTP Client object used to fetch RDF data + * + * If no HTTP Client has previously been set, then a new + * default (EasyRdf_Http_Client) client will be created. + * + * @return object mixed The HTTP client object + */ + public static function getDefaultHttpClient() + { + if (!isset(self::$defaultHttpClient)) { + self::$defaultHttpClient = new EasyRdf_Http_Client(); + } + return self::$defaultHttpClient; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Client.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Client.php new file mode 100644 index 000000000000..57c6fae52399 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Client.php @@ -0,0 +1,549 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 Nicholas J Humfrey. All rights reserved. + * Copyright (c) 2005-2009 Zend Technologies USA Inc. + * + * 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-2012 Nicholas J Humfrey + * Copyright (c) 2005-2009 Zend Technologies USA Inc. + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * This class is an implemetation of an HTTP client in PHP. + * It supports basic HTTP 1.0 and 1.1 requests. For a more complete + * implementation try Zend_Http_Client. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Http_Client +{ + /** + * Configuration array, set using the constructor or using ::setConfig() + * + * @var array + */ + private $config = array( + 'maxredirects' => 5, + 'useragent' => 'EasyRdf_Http_Client', + 'timeout' => 10 + ); + + /** + * Request URI + * + * @var string + */ + private $uri = null; + + /** + * Associative array of request headers + * + * @var array + */ + private $headers = array(); + + /** + * HTTP request method + * + * @var string + */ + private $method = 'GET'; + + /** + * Associative array of GET parameters + * + * @var array + */ + private $paramsGet = array(); + + /** + * The raw post data to send. Could be set by setRawData($data). + * + * @var string + */ + private $rawPostData = null; + + /** + * Redirection counter + * + * @var int + */ + private $redirectCounter = 0; + + /** + * Constructor method. Will create a new HTTP client. Accepts the target + * URL and optionally configuration array. + * + * @param string $uri + * @param array $config Configuration key-value pairs. + */ + public function __construct($uri = null, $config = null) + { + if ($uri !== null) { + $this->setUri($uri); + } + if ($config !== null) { + $this->setConfig($config); + } + } + + /** + * Set the URI for the next request + * + * @param string $uri + * @return EasyRdf_Http_Client + */ + public function setUri($uri) + { + if (!is_string($uri)) { + $uri = strval($uri); + } + + if (!preg_match('/^http(s?):/', $uri)) { + throw new InvalidArgumentException( + "EasyRdf_Http_Client only supports the 'http' and 'https' schemes." + ); + } + + $this->uri = $uri; + + return $this; + } + + /** + * Get the URI for the next request + * + * @return string + */ + public function getUri($asString = true) + { + return $this->uri; + } + + /** + * Set configuration parameters for this HTTP client + * + * @param array $config + * @return EasyRdf_Http_Client + * @throws InvalidArgumentException + */ + public function setConfig($config = array()) + { + if ($config == null or !is_array($config)) { + throw new InvalidArgumentException( + "\$config should be an array and cannot be null" + ); + } + + foreach ($config as $k => $v) { + $this->config[strtolower($k)] = $v; + } + + return $this; + } + + /** + * Set a request header + * + * @param string $name Header name (e.g. 'Accept') + * @param string $value Header value or null + * @return EasyRdf_Http_Client + */ + public function setHeaders($name, $value = null) + { + $normalizedName = strtolower($name); + + // If $value is null or false, unset the header + if ($value === null || $value === false) { + unset($this->headers[$normalizedName]); + } else { + // Else, set the header + $this->headers[$normalizedName] = array($name, $value); + } + + return $this; + } + + /** + * Set the next request's method + * + * Validated the passed method and sets it. + * + * @param string $method + * @return EasyRdf_Http_Client + * @throws InvalidArgumentException + */ + public function setMethod($method) + { + if (!is_string($method) or !preg_match('/^[A-Z]+$/', $method)) { + throw new InvalidArgumentException("Invalid HTTP request method."); + } + + $this->method = $method; + + return $this; + } + + /** + * Get the method for the next request + * + * @return string + */ + public function getMethod() + { + return $this->method; + } + + /** + * Get the value of a specific header + * + * Note that if the header has more than one value, an array + * will be returned. + * + * @param string $key + * @return string|array|null The header value or null if it is not set + */ + public function getHeader($key) + { + $key = strtolower($key); + if (isset($this->headers[$key])) { + return $this->headers[$key][1]; + } else { + return null; + } + } + + /** + * Set a GET parameter for the request. + * + * @param string $name + * @param string $value + * @return EasyRdf_Http_Client + */ + public function setParameterGet($name, $value = null) + { + if ($value === null) { + if (isset($this->paramsGet[$name])) { + unset($this->paramsGet[$name]); + } + } else { + $this->paramsGet[$name] = $value; + } + + return $this; + } + + /** + * Get a GET parameter for the request. + * + * @param string $name + * @return string value + */ + public function getParameterGet($name) + { + if (isset($this->paramsGet[$name])) { + return $this->paramsGet[$name]; + } else { + return null; + } + } + + /** + * Get all the GET parameters + * + * @return array + */ + public function getParametersGet() + { + return $this->paramsGet; + } + + /** + * Get the number of redirections done on the last request + * + * @return int + */ + public function getRedirectionsCount() + { + return $this->redirectCounter; + } + + /** + * Set the raw (already encoded) POST data. + * + * This function is here for two reasons: + * 1. For advanced user who would like to set their own data, already encoded + * 2. For backwards compatibilty: If someone uses the old post($data) method. + * this method will be used to set the encoded data. + * + * $data can also be stream (such as file) from which the data will be read. + * + * @param string|resource $data + * @return Zend_Http_Client + */ + public function setRawData($data) + { + $this->rawPostData = $data; + return $this; + } + + /** + * Get the raw (already encoded) POST data. + * + * @return string + */ + public function getRawData() + { + return $this->rawPostData; + } + + /** + * Clear all GET and POST parameters + * + * Should be used to reset the request parameters if the client is + * used for several concurrent requests. + * + * clearAll parameter controls if we clean just parameters or also + * headers + * + * @param bool $clearAll Should all data be cleared? + * @return EasyRdf_Http_Client + */ + public function resetParameters($clearAll = false) + { + // Reset parameter data + $this->paramsGet = array(); + $this->rawPostData = null; + $this->method = 'GET'; + + if ($clearAll) { + $this->headers = array(); + } else { + // Clear outdated headers + if (isset($this->headers['content-type'])) { + unset($this->headers['content-type']); + } + if (isset($this->headers['content-length'])) { + unset($this->headers['content-length']); + } + } + + return $this; + } + + /** + * Send the HTTP request and return an HTTP response object + * + * @return EasyRdf_Http_Response + * @throws EasyRdf_Exception + */ + public function request($method = null) + { + if (!$this->uri) { + throw new EasyRdf_Exception( + "Set URI before calling EasyRdf_Http_Client->request()" + ); + } + + if ($method) { + $this->setMethod($method); + } + $this->redirectCounter = 0; + $response = null; + + // Send the first request. If redirected, continue. + do { + // Clone the URI and add the additional GET parameters to it + $uri = parse_url($this->uri); + if ($uri['scheme'] === 'http') { + $host = $uri['host']; + } elseif ($uri['scheme'] === 'https') { + $host = 'ssl://'.$uri['host']; + } else { + throw new EasyRdf_Exception( + "Unsupported URI scheme: ".$uri['scheme'] + ); + } + + if (isset($uri['port'])) { + $port = $uri['port']; + } else { + if ($uri['scheme'] === 'https') { + $port = 443; + } else { + $port = 80; + } + } + + if (!empty($this->paramsGet)) { + if (!empty($uri['query'])) { + $uri['query'] .= '&'; + } else { + $uri['query'] = ''; + } + $uri['query'] .= http_build_query($this->paramsGet, null, '&'); + } + + $headers = $this->prepareHeaders($uri['host'], $port); + + // Open socket to remote server + $socket = @fsockopen($host, $port, $errno, $errstr, $this->config['timeout']); + if (!$socket) { + throw new EasyRdf_Exception("Unable to connect to $host:$port ($errstr)"); + } + + // Write the request + $path = $uri['path']; + if (isset($uri['query'])) { + $path .= '?' . $uri['query']; + } + fwrite($socket, "{$this->method} {$path} HTTP/1.1\r\n"); + foreach ($headers as $k => $v) { + if (is_string($k)) { + $v = ucfirst($k) . ": $v"; + } + fwrite($socket, "$v\r\n"); + } + fwrite($socket, "\r\n"); + + // Send the request body, if there is one set + if (isset($this->rawPostData)) { + fwrite($socket, $this->rawPostData); + } + + // Read in the response + $content = ''; + while (!feof($socket)) { + $content .= fgets($socket); + } + + // FIXME: support HTTP/1.1 100 Continue + + // Close the socket + @fclose($socket); + + // Parse the response string + $response = EasyRdf_Http_Response::fromString($content); + + // If we got redirected, look for the Location header + if ($response->isRedirect() && + ($location = $response->getHeader('location')) + ) { + + // Avoid problems with buggy servers that add whitespace at the + // end of some headers (See ZF-11283) + $location = trim($location); + + // Some servers return relative URLs in the location header + // resolve it in relation to previous request + $baseUri = new EasyRdf_ParsedUri($this->uri); + $location = $baseUri->resolve($location)->toString(); + + // If it is a 303 then drop the parameters and send a GET request + if ($response->getStatus() == 303) { + $this->resetParameters(); + $this->setMethod('GET'); + } + + // If we got a well formed absolute URI + if (parse_url($location)) { + $this->setHeaders('host', null); + $this->setUri($location); + } else { + throw new EasyRdf_Exception( + "Failed to parse Location header returned by ". + $this->uri + ); + } + ++$this->redirectCounter; + + } else { + // If we didn't get any location, stop redirecting + break; + } + + + } while ($this->redirectCounter < $this->config['maxredirects']); + + return $response; + } + + /** + * Prepare the request headers + * + * @ignore + * @return array + */ + protected function prepareHeaders($host, $port) + { + $headers = array(); + + // Set the host header + if (! isset($this->headers['host'])) { + // If the port is not default, add it + if ($port !== 80 and $port !== 443) { + $host .= ':' . $port; + } + $headers[] = "Host: {$host}"; + } + + // Set the connection header + if (! isset($this->headers['connection'])) { + $headers[] = "Connection: close"; + } + + // Set the user agent header + if (! isset($this->headers['user-agent'])) { + $headers[] = "User-Agent: {$this->config['useragent']}"; + } + + // If we have _rawPostData set, set the content-length header + if (isset($this->rawPostData)) { + $headers[] = "Content-Length: ".strlen($this->rawPostData); + } + + // Add all other user defined headers + foreach ($this->headers as $header) { + list($name, $value) = $header; + if (is_array($value)) { + $value = implode(', ', $value); + } + + $headers[] = "$name: $value"; + } + + return $headers; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Response.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Response.php new file mode 100644 index 000000000000..2abe00aca182 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Http/Response.php @@ -0,0 +1,361 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 Nicholas J Humfrey. + * Copyright (c) 2005-2009 Zend Technologies USA Inc. + * 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-2010 Nicholas J Humfrey + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an HTTP 1.0 / 1.1 response message. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * Copyright (c) 2005-2009 Zend Technologies USA Inc. + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Http_Response +{ + + /** + * The HTTP response status code + * + * @var int + */ + private $status; + + /** + * The HTTP response code as string + * (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500) + * + * @var string + */ + private $message; + + /** + * The HTTP response headers array + * + * @var array + */ + private $headers = array(); + + /** + * The HTTP response body + * + * @var string + */ + private $body; + + /** + * Constructor. + * + * @param int $status HTTP Status code + * @param array $headers The HTTP response headers + * @param string $body The content of the response + * @param string $version The HTTP Version (1.0 or 1.1) + * @param string $message The HTTP response Message + * @return object EasyRdf_Http_Response + */ + public function __construct( + $status, + $headers, + $body = null, + $version = '1.1', + $message = null + ) { + $this->status = intval($status); + $this->body = $body; + $this->version = $version; + $this->message = $message; + + foreach ($headers as $k => $v) { + $k = ucwords(strtolower($k)); + $this->headers[$k] = $v; + } + } + + /** + * Check whether the response in successful + * + * @return boolean + */ + public function isSuccessful() + { + return ($this->status >= 200 && $this->status < 300); + } + + /** + * Check whether the response is an error + * + * @return boolean + */ + public function isError() + { + return ($this->status >= 400 && $this->status < 600); + } + + /** + * Check whether the response is a redirection + * + * @return boolean + */ + public function isRedirect() + { + return ($this->status >= 300 && $this->status < 400); + } + + /** + * Get the HTTP response status code + * + * @return int + */ + public function getStatus() + { + return $this->status; + } + + /** + * Return a message describing the HTTP response code + * (Eg. "OK", "Not Found", "Moved Permanently") + * + * @return string + */ + public function getMessage() + { + return $this->message; + } + + /** + * Get the response body as string + * + * @return string + */ + public function getBody() + { + // Decode the body if it was transfer-encoded + switch (strtolower($this->getHeader('transfer-encoding'))) { + // Handle chunked body + case 'chunked': + return self::decodeChunkedBody($this->body); + break; + + // No transfer encoding, or unknown encoding extension: + // return body as is + default: + return $this->body; + break; + } + } + + /** + * Get the raw response body (as transfered "on wire") as string + * + * If the body is encoded (with Transfer-Encoding, not content-encoding - + * IE "chunked" body), gzip compressed, etc. it will not be decoded. + * + * @return string + */ + public function getRawBody() + { + return $this->body; + } + + /** + * Get the HTTP version of the response + * + * @return string + */ + public function getVersion() + { + return $this->version; + } + + /** + * Get the response headers + * + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * Get a specific header as string, or null if it is not set + * + * @param string$header + * @return string|array|null + */ + public function getHeader($header) + { + $header = ucwords(strtolower($header)); + if (array_key_exists($header, $this->headers)) { + return $this->headers[$header]; + } else { + return null; + } + } + + /** + * Get all headers as string + * + * @param boolean $statusLine Whether to return the first status line (ie "HTTP 200 OK") + * @param string $br Line breaks (eg. "\n", "\r\n", "<br />") + * @return string + */ + public function getHeadersAsString($statusLine = true, $br = "\n") + { + $str = ''; + + if ($statusLine) { + $str = "HTTP/{$this->version} {$this->status} {$this->message}{$br}"; + } + + // Iterate over the headers and stringify them + foreach ($this->headers as $name => $value) { + if (is_string($value)) { + $str .= "{$name}: {$value}{$br}"; + } elseif (is_array($value)) { + foreach ($value as $subval) { + $str .= "{$name}: {$subval}{$br}"; + } + } + } + + return $str; + } + + /** + * Create an EasyRdf_Http_Response object from a HTTP response string + * + * @param string $responseStr + * @return EasyRdf_Http_Response + */ + public static function fromString($responseStr) + { + // First, split body and headers + $matches = preg_split('|(?:\r?\n){2}|m', $responseStr, 2); + if ($matches and sizeof($matches) == 2) { + list ($headerLines, $body) = $matches; + } else { + throw new EasyRdf_Exception( + "Failed to parse HTTP response." + ); + } + + // Split headers part to lines + $headerLines = preg_split('|[\r\n]+|m', $headerLines); + $status = array_shift($headerLines); + if (preg_match("|^HTTP/([\d\.x]+) (\d+) ([^\r\n]+)|", $status, $m)) { + $version = $m[1]; + $status = $m[2]; + $message = $m[3]; + } else { + throw new EasyRdf_Exception( + "Failed to parse HTTP response status line." + ); + } + + // Process the rest of the header lines + $headers = array(); + foreach ($headerLines as $line) { + if (preg_match("|^([\w-]+):\s+(.+)$|", $line, $m)) { + $hName = ucwords(strtolower($m[1])); + $hValue = $m[2]; + + if (isset($headers[$hName])) { + if (! is_array($headers[$hName])) { + $headers[$hName] = array($headers[$hName]); + } + $headers[$hName][] = $hValue; + } else { + $headers[$hName] = $hValue; + } + } + } + + return new EasyRdf_Http_Response($status, $headers, $body, $version, $message); + } + + + /** + * Decode a "chunked" transfer-encoded body and return the decoded text + * + * @param string $body + * @return string + */ + public static function decodeChunkedBody($body) + { + $decBody = ''; + + while (trim($body)) { + if (preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) { + $length = hexdec(trim($m[1])); + $cut = strlen($m[0]); + $decBody .= substr($body, $cut, $length); + $body = substr($body, $cut + $length + 2); + } else { + throw new EasyRdf_Exception( + "Failed to decode chunked body in HTTP response." + ); + } + } + + return $decBody; + } + + + /** + * Get the entire response as string + * + * @param string $br Line breaks (eg. "\n", "\r\n", "<br />") + * @return string + */ + public function asString($br = "\n") + { + return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody(); + } + + /** + * Implements magic __toString() + * + * @return string + */ + public function __toString() + { + return $this->asString(); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal.php new file mode 100644 index 000000000000..eadf2a2adf60 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal.php @@ -0,0 +1,315 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal +{ + /** @ignore a mapping from datatype uri to class name */ + private static $datatypeMap = array(); + + /** @ignore A mapping from class name to datatype URI */ + private static $classMap = array(); + + /** @ignore The string value for this literal */ + protected $value = null; + + /** @ignore The language of the literal (e.g. 'en') */ + protected $lang = null; + + /** @ignore The datatype URI of the literal */ + protected $datatype = null; + + + /** Create a new literal object + * + * PHP values of type bool, int or float, will automatically be converted + * to the corresponding datatype and PHP sub-class. + * + * If a registered datatype is given, then the registered subclass of EasyRdf_Literal + * will instantiated. + * + * Note that literals are not required to have a language or datatype. + * Literals cannot have both a language and a datatype. + * + * @param mixed $value The value of the literal or an associative array + * @param string $lang The natural language of the literal or null (e.g. 'en') + * @param string $datatype The datatype of the literal or null (e.g. 'xsd:integer') + * @return object EasyRdf_Literal (or subclass of EasyRdf_Literal) + */ + public static function create($value, $lang = null, $datatype = null) + { + if (EasyRdf_Utils::isAssociativeArray($value)) { + if (isset($value['xml:lang'])) { + $lang = $value['xml:lang']; + } elseif (isset($value['lang'])) { + $lang = $value['lang']; + } + if (isset($value['datatype'])) { + $datatype = $value['datatype']; + } + $value = isset($value['value']) ? $value['value'] : null; + } + + if (empty($datatype)) { + if (empty($lang)) { + // Automatic datatype selection + $datatype = self::getDatatypeForValue($value); + } + } elseif (is_object($datatype)) { + $datatype = strval($datatype); + } else { + // Expand shortened URIs (qnames) + $datatype = EasyRdf_Namespace::expand($datatype); + } + + // Work out what class to use for this datatype + if (isset(self::$datatypeMap[$datatype])) { + $class = self::$datatypeMap[$datatype]; + } else { + $class = 'EasyRdf_Literal'; + } + return new $class($value, $lang, $datatype); + } + + /** Register an RDF datatype with a PHP class name + * + * When parsing registered class will be used whenever the datatype + * is seen. + * + * When serialising a registered class, the mapping will be used to + * set the datatype in the RDF. + * + * Example: + * EasyRdf_Literal::registerDatatype('xsd:dateTime', 'My_DateTime_Class'); + * + * @param string $datatype The RDF datatype (e.g. xsd:dateTime) + * @param string $class The PHP class name (e.g. My_DateTime_Class) + */ + public static function setDatatypeMapping($datatype, $class) + { + if (!is_string($datatype) or $datatype == null or $datatype == '') { + throw new InvalidArgumentException( + "\$datatype should be a string and cannot be null or empty" + ); + } + + if (!is_string($class) or $class == null or $class == '') { + throw new InvalidArgumentException( + "\$class should be a string and cannot be null or empty" + ); + } + + $datatype = EasyRdf_Namespace::expand($datatype); + self::$datatypeMap[$datatype] = $class; + self::$classMap[$class] = $datatype; + } + + /** Remove the mapping between an RDF datatype and a PHP class name + * + * @param string $datatype The RDF datatype (e.g. xsd:dateTime) + */ + public static function deleteDatatypeMapping($datatype) + { + if (!is_string($datatype) or $datatype == null or $datatype == '') { + throw new InvalidArgumentException( + "\$datatype should be a string and cannot be null or empty" + ); + } + + $datatype = EasyRdf_Namespace::expand($datatype); + if (isset(self::$datatypeMap[$datatype])) { + $class = self::$datatypeMap[$datatype]; + unset(self::$datatypeMap[$datatype]); + unset(self::$classMap[$class]); + } + } + + /** Get datatype URI for a PHP value. + * + * This static function is intended for internal use. + * Given a PHP value, it will return an XSD datatype + * URI for that value, for example: + * http://www.w3.org/2001/XMLSchema#integer + * + * @return string A URI for the datatype of $value. + */ + public static function getDatatypeForValue($value) + { + if (is_float($value)) { + return 'http://www.w3.org/2001/XMLSchema#decimal'; + } elseif (is_int($value)) { + return 'http://www.w3.org/2001/XMLSchema#integer'; + } elseif (is_bool($value)) { + return 'http://www.w3.org/2001/XMLSchema#boolean'; + } elseif (is_object($value) and $value instanceof DateTime) { + return 'http://www.w3.org/2001/XMLSchema#dateTime'; + } else { + return null; + } + } + + + + /** Constructor for creating a new literal + * + * @param string $value The value of the literal + * @param string $lang The natural language of the literal or null (e.g. 'en') + * @param string $datatype The datatype of the literal or null (e.g. 'xsd:string') + * @return object EasyRdf_Literal + */ + public function __construct($value, $lang = null, $datatype = null) + { + $this->value = $value; + $this->lang = $lang ? $lang : null; + $this->datatype = $datatype ? $datatype : null; + + if ($this->datatype) { + if (is_object($this->datatype)) { + // Convert objects to strings + $this->datatype = strval($this->datatype); + } else { + // Expand shortened URIs (CURIEs) + $this->datatype = EasyRdf_Namespace::expand($this->datatype); + } + + // Literals can not have both a language and a datatype + $this->lang = null; + } else { + // Set the datatype based on the subclass + $class = get_class($this); + if (isset(self::$classMap[$class])) { + $this->datatype = self::$classMap[$class]; + $this->lang = null; + } + } + + // Cast value to string + settype($this->value, 'string'); + } + + /** Returns the value of the literal. + * + * @return string Value of this literal. + */ + public function getValue() + { + return $this->value; + } + + /** Returns the full datatype URI of the literal. + * + * @return string Datatype URI of this literal. + */ + public function getDatatypeUri() + { + return $this->datatype; + } + + /** Returns the shortened datatype URI of the literal. + * + * @return string Datatype of this literal (e.g. xsd:integer). + */ + public function getDatatype() + { + if ($this->datatype) { + return EasyRdf_Namespace::shorten($this->datatype); + } else { + return null; + } + } + + /** Returns the language of the literal. + * + * @return string Language of this literal. + */ + public function getLang() + { + return $this->lang; + } + + /** Returns the properties of the literal as an associative array + * + * For example: + * array('type' => 'literal', 'value' => 'string value') + * + * @return array The properties of the literal + */ + public function toArray() + { + $array = array( + 'type' => 'literal', + 'value' => $this->value + ); + + if ($this->datatype) { + $array['datatype'] = $this->datatype; + } + + if ($this->lang) { + $array['lang'] = $this->lang; + } + + return $array; + } + + /** Magic method to return the value of a literal as a string + * + * @return string The value of the literal + */ + public function __toString() + { + return isset($this->value) ? $this->value : ''; + } + + /** Return pretty-print view of the literal + * + * @param bool $html Set to true to format the dump using HTML + * @param string $color The colour of the text + * @return string + */ + public function dumpValue($html = true, $color = 'black') + { + return EasyRdf_Utils::dumpLiteralValue($this, $html, $color); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Boolean.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Boolean.php new file mode 100644 index 000000000000..d43863a99646 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Boolean.php @@ -0,0 +1,96 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:boolean + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#boolean + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_Boolean extends EasyRdf_Literal +{ + /** Constructor for creating a new boolean literal + * + * If the value is not a string, then it will be converted to 'true' or 'false'. + * + * @param mixed $value The value of the literal + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:boolean') + * @return object EasyRdf_Literal_Boolean + */ + public function __construct($value, $lang = null, $datatype = null) + { + if (!is_string($value)) { + $value = $value ? 'true' : 'false'; + } + parent::__construct($value, null, $datatype); + } + + /** Return the value of the literal cast to a PHP bool + * + * If the value is 'true' or '1' return true, otherwise returns false. + * + * @return bool + */ + public function getValue() + { + return strtolower($this->value) === 'true' or $this->value === '1'; + } + + /** Return true if the value of the literal is 'true' or '1' + * + * @return bool + */ + public function isTrue() + { + return strtolower($this->value) === 'true' or $this->value === '1'; + } + + /** Return true if the value of the literal is 'false' or '0' + * + * @return bool + */ + public function isFalse() + { + return strtolower($this->value) === 'false' or $this->value === '0'; + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:boolean', 'EasyRdf_Literal_Boolean'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Date.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Date.php new file mode 100644 index 000000000000..fb1a687b11b9 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Date.php @@ -0,0 +1,134 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:date + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#date + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_Date extends EasyRdf_Literal +{ + /** Constructor for creating a new date literal + * + * If the value is a DateTime object, then it will be converted to the xsd:date format. + * + * @see DateTime + * + * @param mixed $value The value of the literal + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:date') + * @return object EasyRdf_Literal_Date + */ + public function __construct($value, $lang = null, $datatype = null) + { + // Convert DateTime object into string + if ($value instanceof DateTime) { + $value = $value->format('Y-m-d'); + } + + parent::__construct($value, null, $datatype); + } + + /** Parses a string using DateTime and creates a new literal + * + * Example: + * $date = EasyRdf_Literal_Date::parse('1 January 2011'); + * + * @see DateTime + * @param string $value The date to parse + * @return object EasyRdf_Literal_Date + */ + public static function parse($value) + { + $value = new DateTime($value); + return new EasyRdf_Literal_Date($value); + } + + /** Returns the date as a PHP DateTime object + * + * @see DateTime::format + * @return string + */ + public function getValue() + { + return new DateTime($this->value); + } + + /** Returns date formatted according to given format + * + * @see DateTime::format + * @param string $format + * @return string + */ + public function format($format) + { + return $this->getValue()->format($format); + } + + /** A full integer representation of the year, 4 digits + * + * @return integer + */ + public function year() + { + return (int)$this->format('Y'); + } + + /** Integer representation of the month + * + * @return integer + */ + public function month() + { + return (int)$this->format('m'); + } + + /** Integer representation of the day of the month + * + * @return integer + */ + public function day() + { + return (int)$this->format('d'); + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:date', 'EasyRdf_Literal_Date'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/DateTime.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/DateTime.php new file mode 100644 index 000000000000..577badf2bfdf --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/DateTime.php @@ -0,0 +1,114 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:dateTime + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#date + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_DateTime extends EasyRdf_Literal_Date +{ + /** Constructor for creating a new date and time literal + * + * If the value is a DateTime object, then it will be converted to the xsd:dateTime format. + * + * @see DateTime + * + * @param mixed $value The value of the literal + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:dateTime') + * @return object EasyRdf_Literal_DateTime + */ + public function __construct($value, $lang = null, $datatype = null) + { + // Convert DateTime objects into string + if ($value instanceof DateTime) { + $iso = $value->format(DateTime::ISO8601); + $value = preg_replace('/[\+\-]00(\:?)00$/', 'Z', $iso); + } + + EasyRdf_Literal::__construct($value, null, $datatype); + } + + /** Parses a string using DateTime and creates a new literal + * + * Example: + * $dt = EasyRdf_Literal_DateTime::parse('Mon 18 Jul 2011 18:45:43 BST'); + * + * @see DateTime + * @param string $value The date and time to parse + * @return object EasyRdf_Literal_DateTime + */ + public static function parse($value) + { + $value = new DateTime($value); + return new EasyRdf_Literal_DateTime($value); + } + + /** 24-hour format of the hour as an integer + * + * @return integer + */ + public function hour() + { + return (int)$this->format('H'); + } + + /** The minutes pasts the hour as an integer + * + * @return integer + */ + public function min() + { + return (int)$this->format('i'); + } + + /** The seconds pasts the minute as an integer + * + * @return integer + */ + public function sec() + { + return (int)$this->format('s'); + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:dateTime', 'EasyRdf_Literal_DateTime'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Decimal.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Decimal.php new file mode 100644 index 000000000000..680c9781cb92 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Decimal.php @@ -0,0 +1,71 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:decimal + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#decimal + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_Decimal extends EasyRdf_Literal +{ + /** Constructor for creating a new decimal literal + * + * @param mixed $value The value of the literal + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:decimal') + * @return object EasyRdf_Literal_Decimal + */ + public function __construct($value, $lang = null, $datatype = null) + { + parent::__construct($value, null, $datatype); + } + + /** Return the value of the literal cast to a PHP double + * + * @return double + */ + public function getValue() + { + return (double)$this->value; + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:decimal', 'EasyRdf_Literal_Decimal'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HTML.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HTML.php new file mode 100644 index 000000000000..2d0f9381f573 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HTML.php @@ -0,0 +1,73 @@ +<?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 + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype rdf:HTML + * + * @package EasyRdf + * @link http://www.w3.org/TR/rdf11-concepts/#section-html + * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_HTML extends EasyRdf_Literal +{ + /** Constructor for creating a new rdf:HTML literal + * + * @param mixed $value The HTML fragment + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'rdf:HTML') + * @return object EasyRdf_Literal_HTML + */ + public function __construct($value, $lang = null, $datatype = null) + { + parent::__construct($value, null, $datatype); + } + + /** Strip the HTML tags from the literal + * + * @link http://php.net/manual/en/function.strip-tags.php + * @param string $allowableTags Optional allowed tag, not be be removed + * @return string The literal as plain text + */ + public function stripTags($allowableTags = null) + { + return strip_tags($this->value, $allowableTags); + } +} + +EasyRdf_Literal::setDatatypeMapping('rdf:HTML', 'EasyRdf_Literal_HTML'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HexBinary.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HexBinary.php new file mode 100644 index 000000000000..2077a6e5fd77 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/HexBinary.php @@ -0,0 +1,92 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:hexBinary + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#hexBinary + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_HexBinary extends EasyRdf_Literal +{ + /** Constructor for creating a new xsd:hexBinary literal + * + * @param mixed $value The value of the literal (already encoded as hexadecimal) + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:hexBinary') + * @return object EasyRdf_Literal_HexBinary + */ + public function __construct($value, $lang = null, $datatype = null) + { + // Normalise the canonical representation, as specified here: + // http://www.w3.org/TR/xmlschema-2/#hexBinary-canonical-repr + $value = strtoupper($value); + + // Validate the data + if (preg_match("/[^A-F0-9]/", $value)) { + throw new InvalidArgumentException( + "Literal of type xsd:hexBinary contains non-hexadecimal characters" + ); + } + + parent::__construct(strtoupper($value), null, 'xsd:hexBinary'); + } + + /** Constructor for creating a new literal object from a binary blob + * + * @param string $binary The binary data + * @return object EasyRdf_Literal_HexBinary + */ + public static function fromBinary($binary) + { + return new self( bin2hex($binary) ); + } + + /** Decode the hexadecimal string into a binary blob + * + * @return string The binary blob + */ + public function toBinary() + { + return pack("H*", $this->value); + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:hexBinary', 'EasyRdf_Literal_HexBinary'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Integer.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Integer.php new file mode 100644 index 000000000000..b12682e084e5 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/Integer.php @@ -0,0 +1,71 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype xsd:integer + * + * @package EasyRdf + * @link http://www.w3.org/TR/xmlschema-2/#integer + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_Integer extends EasyRdf_Literal +{ + /** Constructor for creating a new integer literal + * + * @param mixed $value The value of the literal + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'xsd:integer') + * @return object EasyRdf_Literal_Integer + */ + public function __construct($value, $lang = null, $datatype = null) + { + parent::__construct($value, null, $datatype); + } + + /** Return the value of the literal cast to a PHP int + * + * @return double + */ + public function getValue() + { + return (int)$this->value; + } +} + +EasyRdf_Literal::setDatatypeMapping('xsd:integer', 'EasyRdf_Literal_Integer'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/XML.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/XML.php new file mode 100644 index 000000000000..0a90c32d9748 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Literal/XML.php @@ -0,0 +1,74 @@ +<?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 + * @version $Id$ + */ + +/** + * Class that represents an RDF Literal of datatype rdf:XMLLiteral + * + * @package EasyRdf + * @link http://www.w3.org/TR/REC-rdf-syntax/#section-Syntax-XML-literals + * @copyright Copyright (c) 2009-2013 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Literal_XML extends EasyRdf_Literal +{ + /** Constructor for creating a new rdf:XMLLiteral literal + * + * @param mixed $value The XML fragment + * @param string $lang Should be null (literals with a datatype can't have a language) + * @param string $datatype Optional datatype (default 'rdf:XMLLiteral') + * @return object EasyRdf_Literal_XML + */ + public function __construct($value, $lang = null, $datatype = null) + { + parent::__construct($value, null, $datatype); + } + + /** Parse the XML literal into a DOMDocument + * + * @link http://php.net/manual/en/domdocument.loadxml.php + * @return object DOMDocument + */ + public function domParse() + { + $dom = new DOMDocument(); + $dom->loadXML($this->value); + return $dom; + } +} + +EasyRdf_Literal::setDatatypeMapping('rdf:XMLLiteral', 'EasyRdf_Literal_XML'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Namespace.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Namespace.php new file mode 100644 index 000000000000..61437b54b9f6 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Namespace.php @@ -0,0 +1,349 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * A namespace registry and manipulation class. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Namespace +{ + /** Namespace registry + * + * List of default namespaces come from: + * - http://www.w3.org/2011/rdfa-context/rdfa-1.1 + * + * With a few extras added. + * + */ + private static $namespaces = array( + 'bibo' => 'http://purl.org/ontology/bibo/', + 'cc' => 'http://creativecommons.org/ns#', + 'cert' => 'http://www.w3.org/ns/auth/cert#', + 'ctag' => 'http://commontag.org/ns#', + 'dc' => 'http://purl.org/dc/terms/', + 'dc11' => 'http://purl.org/dc/elements/1.1/', + 'dcterms' => 'http://purl.org/dc/terms/', + 'doap' => 'http://usefulinc.com/ns/doap#', + 'exif' => 'http://www.w3.org/2003/12/exif/ns#', + 'foaf' => 'http://xmlns.com/foaf/0.1/', + 'geo' => 'http://www.w3.org/2003/01/geo/wgs84_pos#', + 'gr' => 'http://purl.org/goodrelations/v1#', + 'grddl' => 'http://www.w3.org/2003/g/data-view#', + 'ical' => 'http://www.w3.org/2002/12/cal/icaltzd#', + 'ma' => 'http://www.w3.org/ns/ma-ont#', + 'og' => 'http://ogp.me/ns#', + 'owl' => 'http://www.w3.org/2002/07/owl#', + 'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', + 'rdfa' => 'http://www.w3.org/ns/rdfa#', + 'rdfs' => 'http://www.w3.org/2000/01/rdf-schema#', + 'rev' => 'http://purl.org/stuff/rev#', + 'rif' => 'http://www.w3.org/2007/rif#', + 'rss' => 'http://purl.org/rss/1.0/', + 'schema' => 'http://schema.org/', + 'sioc' => 'http://rdfs.org/sioc/ns#', + 'skos' => 'http://www.w3.org/2004/02/skos/core#', + 'skosxl' => 'http://www.w3.org/2008/05/skos-xl#', + 'synd' => 'http://purl.org/rss/1.0/modules/syndication/', + 'v' => 'http://rdf.data-vocabulary.org/#', + 'vcard' => 'http://www.w3.org/2006/vcard/ns#', + 'void' => 'http://rdfs.org/ns/void#', + 'wdr' => 'http://www.w3.org/2007/05/powder#', + 'wdrs' => 'http://www.w3.org/2007/05/powder-s#', + 'wot' => 'http://xmlns.com/wot/0.1/', + 'xhv' => 'http://www.w3.org/1999/xhtml/vocab#', + 'xml' => 'http://www.w3.org/XML/1998/namespace', + 'xsd' => 'http://www.w3.org/2001/XMLSchema#', + ); + + private static $default = null; + + /** Counter for numbering anonymous namespaces */ + private static $anonymousNamespaceCount = 0; + + /** + * Return all the namespaces registered + * + * @return array Associative array of all the namespaces. + */ + public static function namespaces() + { + return self::$namespaces; + } + + /** + * Return a namespace given its prefix. + * + * @param string $prefix The namespace prefix (eg 'foaf') + * @return string The namespace URI (eg 'http://xmlns.com/foaf/0.1/') + */ + public static function get($prefix) + { + if (!is_string($prefix) or $prefix === null or $prefix === '') { + throw new InvalidArgumentException( + "\$prefix should be a string and cannot be null or empty" + ); + } + + if (preg_match('/\W/', $prefix)) { + throw new InvalidArgumentException( + "\$prefix should only contain alpha-numeric characters" + ); + } + + $prefix = strtolower($prefix); + if (array_key_exists($prefix, self::$namespaces)) { + return self::$namespaces[$prefix]; + } else { + return null; + } + } + + /** + * Register a new namespace. + * + * @param string $prefix The namespace prefix (eg 'foaf') + * @param string $long The namespace URI (eg 'http://xmlns.com/foaf/0.1/') + */ + public static function set($prefix, $long) + { + if (!is_string($prefix) or $prefix === null or $prefix === '') { + throw new InvalidArgumentException( + "\$prefix should be a string and cannot be null or empty" + ); + } + + if (preg_match('/\W/', $prefix)) { + throw new InvalidArgumentException( + "\$prefix should only contain alpha-numeric characters" + ); + } + + if (!is_string($long) or $long === null or $long === '') { + throw new InvalidArgumentException( + "\$long should be a string and cannot be null or empty" + ); + } + + $prefix = strtolower($prefix); + self::$namespaces[$prefix] = $long; + } + + /** + * Get the default namespace + * + * Returns the URI of the default namespace or null + * if no default namespace is defined. + * + * @return string The URI of the default namespace + */ + public static function getDefault() + { + return self::$default; + } + + /** + * Set the default namespace + * + * Set the default namespace to either a URI or the prefix of + * an already defined namespace. + * + * Example: + * EasyRdf_Namespace::setDefault('http://schema.org/'); + * + * @param string $namespace The URI or prefix of a namespace (eg 'og') + */ + public static function setDefault($namespace) + { + if (empty($namespace)) { + self::$default = null; + } elseif (preg_match("/^\w+$/", $namespace)) { + if (isset(self::$namespaces[$namespace])) { + self::$default = self::$namespaces[$namespace]; + } else { + throw new InvalidArgumentException( + "Unable to set default namespace to unknown prefix: $namespace" + ); + } + } else { + self::$default = $namespace; + } + } + + /** + * Delete an existing namespace. + * + * @param string $prefix The namespace prefix (eg 'foaf') + */ + public static function delete($prefix) + { + if (!is_string($prefix) or $prefix === null or $prefix === '') { + throw new InvalidArgumentException( + "\$prefix should be a string and cannot be null or empty" + ); + } + + $prefix = strtolower($prefix); + if (isset(self::$namespaces[$prefix])) { + unset(self::$namespaces[$prefix]); + } + } + + /** + * Delete the anonymous namespaces and reset the counter to 0 + */ + public static function reset() + { + while (self::$anonymousNamespaceCount > 0) { + self::delete('ns'.(self::$anonymousNamespaceCount-1)); + self::$anonymousNamespaceCount--; + } + } + + /** + * Try and breakup a URI into a prefix and local part + * + * If $createNamespace is true, and the URI isn't part of an existing + * namespace, then EasyRdf will attempt to create a new namespace and + * return the name of the new prefix (for example 'ns0', 'term'). + * + * If it isn't possible to split the URI, then null will be returned. + * + * @param string $uri The full URI (eg 'http://xmlns.com/foaf/0.1/name') + * @param bool $createNamespace If true, a new namespace will be created + * @return array The split URI (eg 'foaf', 'name') or null + */ + public static function splitUri($uri, $createNamespace = false) + { + if ($uri === null or $uri === '') { + throw new InvalidArgumentException( + "\$uri cannot be null or empty" + ); + } + + if (is_object($uri) and ($uri instanceof EasyRdf_Resource)) { + $uri = $uri->getUri(); + } elseif (!is_string($uri)) { + throw new InvalidArgumentException( + "\$uri should be a string or EasyRdf_Resource" + ); + } + + foreach (self::$namespaces as $prefix => $long) { + if (substr($uri, 0, strlen($long)) == $long) { + return array($prefix, substr($uri, strlen($long))); + } + } + + if ($createNamespace) { + // Try and create a new namespace + # FIXME: check the valid characters for an XML element name + if (preg_match("/^(.+?)([\w\-]+)$/", $uri, $matches)) { + $prefix = "ns".(self::$anonymousNamespaceCount++); + self::set($prefix, $matches[1]); + return array($prefix, $matches[2]); + } + } + + return null; + } + + /** + * Return the prefix namespace that a URI belongs to. + * + * @param string $uri A full URI (eg 'http://xmlns.com/foaf/0.1/name') + * @return string The prefix namespace that it is a part of(eg 'foaf') + */ + public static function prefixOfUri($uri) + { + if ($parts = self::splitUri($uri)) { + return $parts[0]; + } + } + + /** + * Shorten a URI by substituting in the namespace prefix. + * + * If $createNamespace is true, and the URI isn't part of an existing + * namespace, then EasyRdf will attempt to create a new namespace and + * use that namespace to shorten the URI (for example ns0:term). + * + * If it isn't possible to shorten the URI, then null will be returned. + * + * @param string $uri The full URI (eg 'http://xmlns.com/foaf/0.1/name') + * @param bool $createNamespace If true, a new namespace will be created + * @return string The shortened URI (eg 'foaf:name') or null + */ + public static function shorten($uri, $createNamespace = false) + { + if ($parts = self::splitUri($uri, $createNamespace)) { + return implode(':', $parts); + } + } + + /** + * Expand a shortened URI (qname) back into a full URI. + * + * If it isn't possible to expand the qname, for example if the namespace + * isn't registered, then the original string will be returned. + * + * @param string $shortUri The short URI (eg 'foaf:name') + * @return string The full URI (eg 'http://xmlns.com/foaf/0.1/name') + */ + public static function expand($shortUri) + { + if (!is_string($shortUri) or empty($shortUri)) { + throw new InvalidArgumentException( + "\$shortUri should be a string and cannot be null or empty" + ); + } + + if (preg_match("/^(\w+?):([\w\-]+)$/", $shortUri, $matches)) { + $long = self::get($matches[1]); + if ($long) { + return $long . $matches[2]; + } + } elseif (preg_match("/^(\w+)$/", $shortUri) and isset(self::$default)) { + return self::$default . $shortUri; + } + + return $shortUri; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/ParsedUri.php b/core/vendor/njh/easyrdf/lib/EasyRdf/ParsedUri.php new file mode 100644 index 000000000000..0e9f2456a0b8 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/ParsedUri.php @@ -0,0 +1,341 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + + +/** + * A RFC3986 compliant URI parser + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @link http://www.ietf.org/rfc/rfc3986.txt + */ +class EasyRdf_ParsedUri +{ + // For all URIs: + private $scheme = null; + private $fragment = null; + + // For hierarchical URIs: + private $authority = null; + private $path = null; + private $query = null; + + const URI_REGEX = "|^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?|"; + + /** Constructor for creating a new parsed URI + * + * The $uri parameter can either be a string or an + * associative array with the following keys: + * scheme, authority, path, query, fragment + * + * @param mixed $uri The URI as a string or an array + * @return object EasyRdf_ParsedUri + */ + public function __construct($uri = null) + { + if (is_string($uri)) { + if (preg_match(self::URI_REGEX, $uri, $matches)) { + if (!empty($matches[1])) { + $this->scheme = isset($matches[2]) ? $matches[2] : ''; + } + if (!empty($matches[3])) { + $this->authority = isset($matches[4]) ? $matches[4] : ''; + } + $this->path = isset($matches[5]) ? $matches[5] : ''; + if (!empty($matches[6])) { + $this->query = isset($matches[7]) ? $matches[7] : ''; + } + if (!empty($matches[8])) { + $this->fragment = isset($matches[9]) ? $matches[9] : ''; + } + } + } elseif (is_array($uri)) { + $this->scheme = isset($uri['scheme']) ? $uri['scheme'] : null; + $this->authority = isset($uri['authority']) ? $uri['authority'] : null; + $this->path = isset($uri['path']) ? $uri['path'] : null; + $this->query = isset($uri['query']) ? $uri['query'] : null; + $this->fragment = isset($uri['fragment']) ? $uri['fragment'] : null; + } + } + + + /** Returns true if this is an absolute (complete) URI + * @return boolean + */ + public function isAbsolute() + { + return $this->scheme !== null; + } + + /** Returns true if this is an relative (partial) URI + * @return boolean + */ + public function isRelative() + { + return $this->scheme === null; + } + + /** Returns the scheme of the URI (e.g. http) + * @return string + */ + public function getScheme() + { + return $this->scheme; + } + + /** Sets the scheme of the URI (e.g. http) + * @param string $scheme The new value for the scheme of the URI + */ + public function setScheme($scheme) + { + $this->scheme = $scheme; + } + + /** Returns the authority of the URI (e.g. www.example.com:8080) + * @return string + */ + public function getAuthority() + { + return $this->authority; + } + + /** Sets the authority of the URI (e.g. www.example.com:8080) + * @param string $authority The new value for the authority component of the URI + */ + public function setAuthority($authority) + { + $this->authority = $authority; + } + + /** Returns the path of the URI (e.g. /foo/bar) + * @return string + */ + public function getPath() + { + return $this->path; + } + + /** Set the path of the URI (e.g. /foo/bar) + * @param string $path The new value for the path component of the URI + */ + public function setPath($path) + { + $this->path = $path; + } + + /** Returns the query string part of the URI (e.g. foo=bar) + * @return string + */ + public function getQuery() + { + return $this->query; + } + + /** Set the query string of the URI (e.g. foo=bar) + * @param string $query The new value for the query string component of the URI + */ + public function setQuery($query) + { + $this->query = $query; + } + + /** Returns the fragment part of the URI (i.e. after the #) + * @return string + */ + public function getFragment() + { + return $this->fragment; + } + + /** Set the fragment of the URI (i.e. after the #) + * @param string $fragment The new value for the fragment component of the URI + */ + public function setFragment($fragment) + { + $this->fragment = $fragment; + } + + + /** + * Normalises the path of this URI if it has one. Normalising a path means + * that any unnecessary '.' and '..' segments are removed. For example, the + * URI http://example.com/a/b/../c/./d would be normalised to + * http://example.com/a/c/d + * + * @return object EasyRdf_ParsedUri + */ + public function normalise() + { + if (empty($this->path)) { + return $this; + } + + // Remove ./ from the start + if (substr($this->path, 0, 2) == './') { + // Remove both characters + $this->path = substr($this->path, 2); + } + + // Remove /. from the end + if (substr($this->path, -2) == '/.') { + // Remove only the last dot, not the slash! + $this->path = substr($this->path, 0, -1); + } + + if (substr($this->path, -3) == '/..') { + $this->path .= '/'; + } + + // Split the path into its segments + $segments = explode('/', $this->path); + $newSegments = array(); + + // Remove all unnecessary '.' and '..' segments + foreach ($segments as $segment) { + if ($segment == '..') { + // Remove the previous part of the path + $count = count($newSegments); + if ($count > 0 && $newSegments[$count-1]) { + array_pop($newSegments); + } + } elseif ($segment == '.') { + // Ignore + continue; + } else { + array_push($newSegments, $segment); + } + } + + // Construct the new normalised path + $this->path = implode($newSegments, '/'); + + // Allow easy chaining of methods + return $this; + } + + /** + * Resolves a relative URI using this URI as the base URI. + */ + public function resolve($relUri) + { + // If it is a string, then convert it to a parsed object + if (is_string($relUri)) { + $relUri = new EasyRdf_ParsedUri($relUri); + } + + // This code is based on the pseudocode in section 5.2.2 of RFC3986 + $target = new EasyRdf_ParsedUri(); + if ($relUri->scheme) { + $target->scheme = $relUri->scheme; + $target->authority = $relUri->authority; + $target->path = $relUri->path; + $target->query = $relUri->query; + } else { + if ($relUri->authority) { + $target->authority = $relUri->authority; + $target->path = $relUri->path; + $target->query = $relUri->query; + } else { + if (empty($relUri->path)) { + $target->path = $this->path; + if ($relUri->query) { + $target->query = $relUri->query; + } else { + $target->query = $this->query; + } + } else { + if (substr($relUri->path, 0, 1) == '/') { + $target->path = $relUri->path; + } else { + $path = $this->path; + $lastSlash = strrpos($path, '/'); + if ($lastSlash !== false) { + $path = substr($path, 0, $lastSlash + 1); + } else { + $path = '/'; + } + + $target->path .= $path . $relUri->path; + } + $target->query = $relUri->query; + } + $target->authority = $this->authority; + } + $target->scheme = $this->scheme; + } + + $target->fragment = $relUri->fragment; + + $target->normalise(); + + return $target; + } + + /** Convert the parsed URI back into a string + * + * @return string The URI as a string + */ + public function toString() + { + $str = ''; + if ($this->scheme !== null) { + $str .= $this->scheme . ':'; + } + if ($this->authority !== null) { + $str .= '//' . $this->authority; + } + $str .= $this->path; + if ($this->query !== null) { + $str .= '?' . $this->query; + } + if ($this->fragment !== null) { + $str .= '#' . $this->fragment; + } + return $str; + } + + /** Magic method to convert the URI, when casted, back to a string + * + * @return string The URI as a string + */ + public function __toString() + { + return $this->toString(); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser.php new file mode 100644 index 000000000000..b077847c464a --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser.php @@ -0,0 +1,150 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Parent class for the EasyRdf parsers + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser +{ + /** Mapping from source to graph bnode identifiers */ + private $bnodeMap = array(); + + /** The current graph to insert triples into */ + protected $graph = null; + + /** The format of the document currently being parsed */ + protected $format = null; + + /** The base URI for the document currently being parsed */ + protected $baseUri = null; + + /** + * Create a new, unique bnode identifier from a source identifier. + * If the source identifier has previously been seen, the + * same new bnode identifier is returned. + * @ignore + */ + protected function remapBnode($name) + { + if (!isset($this->bnodeMap[$name])) { + $this->bnodeMap[$name] = $this->graph->newBNodeId(); + } + return $this->bnodeMap[$name]; + } + + /** + * Delete the bnode mapping - to be called at the start of a new parse + * @ignore + */ + protected function resetBnodeMap() + { + $this->bnodeMap = array(); + } + + /** + * Check, cleanup parameters and prepare for parsing + * @ignore + */ + protected function checkParseParams($graph, $data, $format, $baseUri) + { + if ($graph == null or !is_object($graph) or + !($graph instanceof EasyRdf_Graph)) { + throw new InvalidArgumentException( + "\$graph should be an EasyRdf_Graph object and cannot be null" + ); + } else { + $this->graph = $graph; + } + + if ($format == null or $format == '') { + throw new InvalidArgumentException( + "\$format cannot be null or empty" + ); + } elseif (is_object($format) and $format instanceof EasyRdf_Format) { + $this->format = $format = $format->getName(); + } elseif (!is_string($format)) { + throw new InvalidArgumentException( + "\$format should be a string or an EasyRdf_Format object" + ); + } else { + $this->format = $format; + } + + if ($baseUri) { + if (!is_string($baseUri)) { + throw new InvalidArgumentException( + "\$baseUri should be a string" + ); + } else { + $this->baseUri = new EasyRdf_ParsedUri($baseUri); + } + } else { + $this->baseUri = null; + } + + // Prepare for parsing + $this->resetBnodeMap(); + $this->tripleCount = 0; + } + + /** + * Sub-classes must follow this protocol + * @ignore + */ + public function parse($graph, $data, $format, $baseUri) + { + throw new EasyRdf_Exception( + "This method should be overridden by sub-classes." + ); + } + + /** + * Add a triple to the current graph, and keep count of the number of triples + * @ignore + */ + protected function addTriple($resource, $property, $value) + { + $count = $this->graph->add($resource, $property, $value); + $this->tripleCount += $count; + return $count; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Arc.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Arc.php new file mode 100644 index 000000000000..e1a4b068d7cc --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Arc.php @@ -0,0 +1,97 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse RDF using the ARC2 library. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Arc extends EasyRdf_Parser_RdfPhp +{ + private static $supportedTypes = array( + 'rdfxml' => 'RDFXML', + 'turtle' => 'Turtle', + 'ntriples' => 'Turtle', + 'rdfa' => 'SemHTML', + ); + + /** + * Constructor + * + * @return object EasyRdf_Parser_Arc + */ + public function __construct() + { + require_once 'arc/ARC2.php'; + } + + /** + * Parse an RDF document into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + if (array_key_exists($format, self::$supportedTypes)) { + $className = self::$supportedTypes[$format]; + } else { + throw new EasyRdf_Exception( + "EasyRdf_Parser_Arc does not support: $format" + ); + } + + $parser = ARC2::getParser($className); + if ($parser) { + $parser->parse($baseUri, $data); + $rdfphp = $parser->getSimpleIndex(false); + return parent::parse($graph, $rdfphp, 'php', $baseUri); + } else { + throw new EasyRdf_Exception( + "ARC2 failed to get a $className parser." + ); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Json.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Json.php new file mode 100644 index 000000000000..a4a80c98a72f --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Json.php @@ -0,0 +1,156 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * A pure-php class to parse RDF/JSON with no dependancies. + * + * http://n2.talis.com/wiki/RDF_JSON_Specification + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Json extends EasyRdf_Parser_RdfPhp +{ + private $jsonLastErrorExists = false; + + /** + * Constructor + * + * @return object EasyRdf_Parser_Json + */ + public function __construct() + { + $this->jsonLastErrorExists = function_exists('json_last_error'); + } + + /** Return the last JSON parser error as a string + * + * If json_last_error() is not available a generic message will be returned. + * + * @ignore + */ + protected function jsonLastErrorString() + { + if ($this->jsonLastErrorExists) { + switch (json_last_error()) { + case JSON_ERROR_NONE: + return null; + case JSON_ERROR_DEPTH: + return "JSON Parse error: the maximum stack depth has been exceeded"; + case JSON_ERROR_STATE_MISMATCH: + return "JSON Parse error: invalid or malformed JSON"; + case JSON_ERROR_CTRL_CHAR: + return "JSON Parse error: control character error, possibly incorrectly encoded"; + case JSON_ERROR_SYNTAX: + return "JSON Parse syntax error"; + case JSON_ERROR_UTF8: + return "JSON Parse error: malformed UTF-8 characters, possibly incorrectly encoded"; + default: + return "JSON Parse error: unknown"; + } + } else { + return "JSON Parse error"; + } + } + + /** Parse the triple-centric JSON format, as output by libraptor + * + * http://librdf.org/raptor/api/serializer-json.html + * + * @ignore + */ + protected function parseJsonTriples($data, $baseUri) + { + foreach ($data['triples'] as $triple) { + if ($triple['subject']['type'] == 'bnode') { + $subject = $this->remapBnode($triple['subject']['value']); + } else { + $subject = $triple['subject']['value']; + } + + $predicate = $triple['predicate']['value']; + + if ($triple['object']['type'] == 'bnode') { + $object = array( + 'type' => 'bnode', + 'value' => $this->remapBnode($triple['object']['value']) + ); + } else { + $object = $triple['object']; + } + + $this->addTriple($subject, $predicate, $object); + } + + return $this->tripleCount; + } + + /** + * Parse RDF/JSON into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + $this->checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'json') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_Json does not support: $format" + ); + } + + $decoded = @json_decode(strval($data), true); + if ($decoded === null) { + throw new EasyRdf_Exception( + $this->jsonLastErrorString() + ); + } + + if (array_key_exists('triples', $decoded)) { + return $this->parseJsonTriples($decoded, $baseUri); + } else { + return parent::parse($graph, $decoded, 'php', $baseUri); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Ntriples.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Ntriples.php new file mode 100644 index 000000000000..af3503ec3dd4 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Ntriples.php @@ -0,0 +1,199 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * A pure-php class to parse N-Triples with no dependancies. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Ntriples extends EasyRdf_Parser +{ + /** + * Decodes an encoded N-Triples string. Any \-escape sequences are substituted + * with their decoded value. + * + * @param string $str An encoded N-Triples string. + * @return The unencoded string. + **/ + protected function unescapeString($str) + { + if (strpos($str, '\\') === false) { + return $str; + } + + $mappings = array( + 't' => chr(0x09), + 'b' => chr(0x08), + 'n' => chr(0x0A), + 'r' => chr(0x0D), + 'f' => chr(0x0C), + '\"' => chr(0x22), + '\'' => chr(0x27) + ); + foreach ($mappings as $in => $out) { + $str = preg_replace('/\x5c([' . $in . '])/', $out, $str); + } + + if (stripos($str, '\u') === false) { + return $str; + } + + while (preg_match('/\\\(U)([0-9A-F]{8})/', $str, $matches) || + preg_match('/\\\(u)([0-9A-F]{4})/', $str, $matches)) { + $no = hexdec($matches[2]); + if ($no < 128) { + $char = chr($no); + } elseif ($no < 2048) { + $char = chr(($no >> 6) + 192) . + chr(($no & 63) + 128); + } elseif ($no < 65536) { + $char = chr(($no >> 12) + 224) . + chr((($no >> 6) & 63) + 128) . + chr(($no & 63) + 128); + } elseif ($no < 2097152) { + $char = chr(($no >> 18) + 240) . + chr((($no >> 12) & 63) + 128) . + chr((($no >> 6) & 63) + 128) . + chr(($no & 63) + 128); + } else { + $char = ''; + } + $str = str_replace('\\' . $matches[1] . $matches[2], $char, $str); + } + return $str; + } + + /** + * @ignore + */ + protected function parseNtriplesSubject($sub) + { + if (preg_match('/<([^<>]+)>/', $sub, $matches)) { + return $this->unescapeString($matches[1]); + } elseif (preg_match('/_:([A-Za-z0-9]*)/', $sub, $matches)) { + if (empty($matches[1])) { + return $this->graph->newBNodeId(); + } else { + $nodeid = $this->unescapeString($matches[1]); + return $this->remapBnode($nodeid); + } + } else { + throw new EasyRdf_Exception( + "Failed to parse subject: $sub" + ); + } + } + + /** + * @ignore + */ + protected function parseNtriplesObject($obj) + { + if (preg_match('/"(.+)"\^\^<([^<>]+)>/', $obj, $matches)) { + return array( + 'type' => 'literal', + 'value' => $this->unescapeString($matches[1]), + 'datatype' => $this->unescapeString($matches[2]) + ); + } elseif (preg_match('/"(.+)"@([\w\-]+)/', $obj, $matches)) { + return array( + 'type' => 'literal', + 'value' => $this->unescapeString($matches[1]), + 'lang' => $this->unescapeString($matches[2]) + ); + } elseif (preg_match('/"(.*)"/', $obj, $matches)) { + return array('type' => 'literal', 'value' => $this->unescapeString($matches[1])); + } elseif (preg_match('/<([^<>]+)>/', $obj, $matches)) { + return array('type' => 'uri', 'value' => $matches[1]); + } elseif (preg_match('/_:([A-Za-z0-9]*)/', $obj, $matches)) { + if (empty($matches[1])) { + return array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId() + ); + } else { + $nodeid = $this->unescapeString($matches[1]); + return array( + 'type' => 'bnode', + 'value' => $this->remapBnode($nodeid) + ); + } + } else { + throw new EasyRdf_Exception( + "Failed to parse object: $obj" + ); + } + } + + /** + * Parse an N-Triples document into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'ntriples') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_Ntriples does not support: $format" + ); + } + + $lines = preg_split("/[\r\n]+/", strval($data)); + foreach ($lines as $line) { + if (preg_match("/^\s*#/", $line)) { + continue; + } elseif (preg_match("/(.+)\s+<([^<>]+)>\s+(.+)\s*\./", $line, $matches)) { + $this->addTriple( + $this->parseNtriplesSubject($matches[1]), + $this->unescapeString($matches[2]), + $this->parseNtriplesObject($matches[3]) + ); + } + } + + return $this->tripleCount; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rapper.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rapper.php new file mode 100644 index 000000000000..31983b7dfb95 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rapper.php @@ -0,0 +1,103 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse RDF using the 'rapper' command line tool. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Rapper extends EasyRdf_Parser_Json +{ + private $rapperCmd = null; + + const MINIMUM_RAPPER_VERSION = '1.4.17'; + + /** + * Constructor + * + * @param string $rapperCmd Optional path to the rapper command to use. + * @return object EasyRdf_Parser_Rapper + */ + public function __construct($rapperCmd = 'rapper') + { + $result = exec("$rapperCmd --version 2>/dev/null", $output, $status); + if ($status != 0) { + throw new EasyRdf_Exception( + "Failed to execute the command '$rapperCmd': $result" + ); + } elseif (version_compare($result, self::MINIMUM_RAPPER_VERSION) < 0) { + throw new EasyRdf_Exception( + "Version ".self::MINIMUM_RAPPER_VERSION." or higher of rapper is required." + ); + } else { + $this->rapperCmd = $rapperCmd; + } + } + + /** + * Parse an RDF document into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + $json = EasyRdf_Utils::execCommandPipe( + $this->rapperCmd, + array( + '--quiet', + '--input', $format, + '--output', 'json', + '--ignore-errors', + '--input-uri', $baseUri, + '--output-uri', '-', '-' + ), + $data + ); + + // Parse in the JSON + return parent::parse($graph, $json, 'json', $baseUri); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfPhp.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfPhp.php new file mode 100644 index 000000000000..baf92773ebc3 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfPhp.php @@ -0,0 +1,100 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse RDF with no external dependancies. + * + * http://n2.talis.com/wiki/RDF_PHP_Specification + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_RdfPhp extends EasyRdf_Parser +{ + /** + * Constructor + * + * @return object EasyRdf_Parser_RdfPhp + */ + public function __construct() + { + } + + /** + * Parse RDF/PHP into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + $this->checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'php') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_RdfPhp does not support: $format" + ); + } + + foreach ($data as $subject => $properties) { + if (substr($subject, 0, 2) === '_:') { + $subject = $this->remapBnode($subject); + } elseif (preg_match('/^\w+$/', $subject)) { + # Cope with invalid RDF/JSON serialisations that + # put the node name in, without the _: prefix + # (such as net.fortytwo.sesametools.rdfjson) + $subject = $this->remapBnode($subject); + } + + foreach ($properties as $property => $objects) { + foreach ($objects as $object) { + if ($object['type'] === 'bnode') { + $object['value'] = $this->remapBnode($object['value']); + } + $this->addTriple($subject, $property, $object); + } + } + } + + return $this->tripleCount; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfXml.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfXml.php new file mode 100644 index 000000000000..06e27cfcd5e3 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/RdfXml.php @@ -0,0 +1,807 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2010-2011 Nicholas J Humfrey + * Copyright (c) 2004-2010 Benjamin Nowack (based on ARC2_RDFXMLParser.php) + * + * 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) 2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + + +/** + * A pure-php class to parse RDF/XML. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * Copyright (c) 2004-2010 Benjamin Nowack (based on ARC2_RDFXMLParser.php) + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_RdfXml extends EasyRdf_Parser +{ + private $state; + private $xLang; + private $xBase; + private $xml; + private $rdf; + private $nsp; + private $sStack; + private $sCount; + + /** + * Constructor + * + * @return object EasyRdf_Parser_RdfXml + */ + public function __construct() + { + } + + /** @ignore */ + protected function init($graph, $base) + { + $this->graph = $graph; + $this->state = 0; + $this->xLang = null; + $this->xBase = new EasyRdf_ParsedUri($base); + $this->xml = 'http://www.w3.org/XML/1998/namespace'; + $this->rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; + $this->nsp = array($this->xml => 'xml', $this->rdf => 'rdf'); + $this->sStack = array(); + $this->sCount = 0; + } + + /** @ignore */ + protected function initXMLParser() + { + if (!isset($this->xmlParser)) { + $parser = xml_parser_create_ns('UTF-8', ''); + xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); + xml_set_element_handler($parser, 'startElementHandler', 'endElementHandler'); + xml_set_character_data_handler($parser, 'cdataHandler'); + xml_set_start_namespace_decl_handler($parser, 'newNamespaceHandler'); + xml_set_object($parser, $this); + $this->xmlParser = $parser; + } + } + + /** @ignore */ + protected function pushS(&$s) + { + $s['pos'] = $this->sCount; + $this->sStack[$this->sCount] = $s; + $this->sCount++; + } + + /** @ignore */ + protected function popS() + { + $r = array(); + $this->sCount--; + for ($i = 0, $iMax = $this->sCount; $i < $iMax; $i++) { + $r[$i] = $this->sStack[$i]; + } + $this->sStack = $r; + } + + /** @ignore */ + protected function updateS($s) + { + $this->sStack[$s['pos']] = $s; + } + + /** @ignore */ + protected function getParentS() + { + if ($this->sCount && isset($this->sStack[$this->sCount - 1])) { + return $this->sStack[$this->sCount - 1]; + } else { + return false; + } + } + + /** @ignore */ + protected function getParentXBase() + { + if ($p = $this->getParentS()) { + if (isset($p['p_x_base']) && $p['p_x_base']) { + return $p['p_x_base']; + } elseif (isset($p['x_base'])) { + return $p['x_base']; + } else { + return ''; + } + } else { + return $this->xBase; + } + } + + /** @ignore */ + protected function getParentXLang() + { + if ($p = $this->getParentS()) { + if (isset($p['p_x_lang']) && $p['p_x_lang']) { + return $p['p_x_lang']; + } elseif (isset($p['x_lang'])) { + return $p['x_lang']; + } else { + return null; + } + } else { + return $this->xLang; + } + } + + /** @ignore */ + protected function splitURI($v) + { + /* auto-splitting on / or # */ + if (preg_match('/^(.*[\/\#])([^\/\#]+)$/', $v, $m)) { + return array($m[1], $m[2]); + } + /* auto-splitting on last special char, e.g. urn:foo:bar */ + if (preg_match('/^(.*[\:\/])([^\:\/]+)$/', $v, $m)) { + return array($m[1], $m[2]); + } + return array($v, ''); + } + + /** @ignore */ + protected function add($s, $p, $o, $sType, $oType, $oDatatype = null, $oLang = null) + { + $this->addTriple( + $s, + $p, + array( + 'type' => $oType, + 'value' => $o, + 'lang' => $oLang, + 'datatype' => $oDatatype + ) + ); + } + + /** @ignore */ + protected function reify($t, $s, $p, $o, $sType, $oType, $oDatatype = null, $oLang = null) + { + $this->add($t, $this->rdf.'type', $this->rdf.'Statement', 'uri', 'uri'); + $this->add($t, $this->rdf.'subject', $s, 'uri', $sType); + $this->add($t, $this->rdf.'predicate', $p, 'uri', 'uri'); + $this->add($t, $this->rdf.'object', $o, 'uri', $oType, $oDatatype, $oLang); + } + + /** @ignore */ + protected function startElementHandler($p, $t, $a) + { + switch($this->state) { + case 0: + return $this->startState0($t, $a); + case 1: + return $this->startState1($t, $a); + case 2: + return $this->startState2($t, $a); + case 4: + return $this->startState4($t, $a); + case 5: + return $this->startState5($t, $a); + case 6: + return $this->startState6($t, $a); + default: + throw new EasyRdf_Exception( + 'startElementHandler() called at state ' . $this->state . ' in '.$t + ); + } + } + + /** @ignore */ + protected function endElementHandler($p, $t) + { + switch($this->state){ + case 1: + return $this->endState1($t); + case 2: + return $this->endState2($t); + case 3: + return $this->endState3($t); + case 4: + return $this->endState4($t); + case 5: + return $this->endState5($t); + case 6: + return $this->endState6($t); + default: + throw new EasyRdf_Exception( + 'endElementHandler() called at state ' . $this->state . ' in '.$t + ); + } + } + + /** @ignore */ + protected function cdataHandler($p, $d) + { + switch($this->state){ + case 4: + return $this->cdataState4($d); + case 6: + return $this->cdataState6($d); + default: + return false; + } + } + + /** @ignore */ + protected function newNamespaceHandler($p, $prf, $uri) + { + $this->nsp[$uri] = isset($this->nsp[$uri]) ? $this->nsp[$uri] : $prf; + } + + /** @ignore */ + protected function startState0($t, $a) + { + $this->state = 1; + if ($t !== $this->rdf.'RDF') { + $this->startState1($t, $a); + } + } + + /** @ignore */ + protected function startState1($t, $a) + { + $s = array( + 'x_base' => $this->getParentXBase(), + 'x_lang' => $this->getParentXLang(), + 'li_count' => 0, + ); + + if (isset($a[$this->xml.'base'])) { + $s['x_base'] = $this->xBase->resolve($a[$this->xml.'base']); + } + + if (isset($a[$this->xml.'lang'])) { + $s['x_lang'] = $a[$this->xml.'lang']; + } + + /* ID */ + if (isset($a[$this->rdf.'ID'])) { + $s['type'] = 'uri'; + $s['value'] = $s['x_base']->resolve('#'.$a[$this->rdf.'ID']); + /* about */ + } elseif (isset($a[$this->rdf.'about'])) { + $s['type'] = 'uri'; + $s['value'] = $s['x_base']->resolve($a[$this->rdf.'about']); + /* bnode */ + } else { + $s['type'] = 'bnode'; + if (isset($a[$this->rdf.'nodeID'])) { + $s['value'] = $this->remapBnode($a[$this->rdf.'nodeID']); + } else { + $s['value'] = $this->graph->newBNodeId(); + } + } + + /* sub-node */ + if ($this->state === 4) { + $supS = $this->getParentS(); + /* new collection */ + if (isset($supS['o_is_coll']) && $supS['o_is_coll']) { + $coll = array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId(), + 'is_coll' => true, + 'x_base' => $s['x_base'], + 'x_lang' => $s['x_lang'] + ); + $this->add($supS['value'], $supS['p'], $coll['value'], $supS['type'], $coll['type']); + $this->add($coll['value'], $this->rdf.'first', $s['value'], $coll['type'], $s['type']); + $this->pushS($coll); + + } elseif (isset($supS['is_coll']) && $supS['is_coll']) { + /* new entry in existing coll */ + $coll = array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId(), + 'is_coll' => true, + 'x_base' => $s['x_base'], + 'x_lang' => $s['x_lang'] + ); + $this->add($supS['value'], $this->rdf.'rest', $coll['value'], $supS['type'], $coll['type']); + $this->add($coll['value'], $this->rdf.'first', $s['value'], $coll['type'], $s['type']); + $this->pushS($coll); + /* normal sub-node */ + } elseif (isset($supS['p']) && $supS['p']) { + $this->add($supS['value'], $supS['p'], $s['value'], $supS['type'], $s['type']); + } + } + /* typed node */ + if ($t !== $this->rdf.'Description') { + $this->add($s['value'], $this->rdf.'type', $t, $s['type'], 'uri'); + } + /* (additional) typing attr */ + if (isset($a[$this->rdf.'type'])) { + $this->add($s['value'], $this->rdf.'type', $a[$this->rdf.'type'], $s['type'], 'uri'); + } + + /* Seq|Bag|Alt */ + // if (in_array($t, array($this->rdf.'Seq', $this->rdf.'Bag', $this->rdf.'Alt'))) { + // # FIXME: what is this? + // $s['is_con'] = true; + // } + + /* any other attrs (skip rdf and xml, except rdf:_, rdf:value, rdf:Seq) */ + foreach ($a as $k => $v) { + if (((strpos($k, $this->xml) === false) && (strpos($k, $this->rdf) === false)) || + preg_match('/(\_[0-9]+|value|Seq|Bag|Alt|Statement|Property|List)$/', $k)) { + if (strpos($k, ':')) { + $this->add($s['value'], $k, $v, $s['type'], 'literal', null, $s['x_lang']); + } + } + } + $this->pushS($s); + $this->state = 2; + } + + /** @ignore */ + protected function startState2($t, $a) + { + $s = $this->getParentS(); + foreach (array('p_x_base', 'p_x_lang', 'p_id', 'o_is_coll') as $k) { + unset($s[$k]); + } + /* base */ + if (isset($a[$this->xml.'base'])) { + $s['p_x_base'] = $s['x_base']->resolve($a[$this->xml.'base']); + } + $b = isset($s['p_x_base']) && $s['p_x_base'] ? $s['p_x_base'] : $s['x_base']; + /* lang */ + if (isset($a[$this->xml.'lang'])) { + $s['p_x_lang'] = $a[$this->xml.'lang']; + } + $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? $s['p_x_lang'] : $s['x_lang']; + /* adjust li */ + if ($t === $this->rdf.'li') { + $s['li_count']++; + $t = $this->rdf.'_'.$s['li_count']; + } + /* set p */ + $s['p'] = $t; + /* reification */ + if (isset($a[$this->rdf.'ID'])) { + $s['p_id'] = $a[$this->rdf.'ID']; + } + $o = array('value' => null, 'type' => null, 'x_base' => $b, 'x_lang' => $l); + /* resource/rdf:resource */ + if (isset($a['resource'])) { + $a[$this->rdf.'resource'] = $a['resource']; + unset($a['resource']); + } + if (isset($a[$this->rdf.'resource'])) { + $o['type'] = 'uri'; + $o['value'] = $b->resolve($a[$this->rdf.'resource']); + $this->add($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); + /* type */ + if (isset($a[$this->rdf.'type'])) { + $this->add( + $o['value'], + $this->rdf.'type', + $a[$this->rdf.'type'], + 'uri', + 'uri' + ); + } + /* reification */ + if (isset($s['p_id'])) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'] + ); + unset($s['p_id']); + } + $this->state = 3; + } elseif (isset($a[$this->rdf.'nodeID'])) { + /* named bnode */ + $o['value'] = $this->remapBnode($a[$this->rdf.'nodeID']); + $o['type'] = 'bnode'; + $this->add($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); + $this->state = 3; + /* reification */ + if (isset($s['p_id'])) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'] + ); + } + /* parseType */ + } elseif (isset($a[$this->rdf.'parseType'])) { + if ($a[$this->rdf.'parseType'] === 'Literal') { + $s['o_xml_level'] = 0; + $s['o_xml_data'] = ''; + $s['p_xml_literal_level'] = 0; + $s['ns'] = array(); + $this->state = 6; + } elseif ($a[$this->rdf.'parseType'] === 'Resource') { + $o['value'] = $this->graph->newBNodeId(); + $o['type'] = 'bnode'; + $o['hasClosingTag'] = 0; + $this->add($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); + $this->pushS($o); + /* reification */ + if (isset($s['p_id'])) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'] + ); + unset($s['p_id']); + } + $this->state = 2; + } elseif ($a[$this->rdf.'parseType'] === 'Collection') { + $s['o_is_coll'] = true; + $this->state = 4; + } + } else { + /* sub-node or literal */ + $s['o_cdata'] = ''; + if (isset($a[$this->rdf.'datatype'])) { + $s['o_datatype'] = $a[$this->rdf.'datatype']; + } + $this->state = 4; + } + /* any other attrs (skip rdf and xml) */ + foreach ($a as $k => $v) { + if (((strpos($k, $this->xml) === false) && + (strpos($k, $this->rdf) === false)) || + preg_match('/(\_[0-9]+|value)$/', $k)) { + if (strpos($k, ':')) { + if (!$o['value']) { + $o['value'] = $this->graph->newBNodeId(); + $o['type'] = 'bnode'; + $this->add($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); + } + /* reification */ + if (isset($s['p_id'])) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'] + ); + unset($s['p_id']); + } + $this->add($o['value'], $k, $v, $o['type'], 'literal'); + $this->state = 3; + } + } + } + $this->updateS($s); + } + + /** @ignore */ + protected function startState4($t, $a) + { + return $this->startState1($t, $a); + } + + /** @ignore */ + protected function startState5($t, $a) + { + $this->state = 4; + return $this->startState4($t, $a); + } + + /** @ignore */ + protected function startState6($t, $a) + { + $s = $this->getParentS(); + $data = isset($s['o_xml_data']) ? $s['o_xml_data'] : ''; + $ns = isset($s['ns']) ? $s['ns'] : array(); + $parts = $this->splitURI($t); + if (count($parts) === 1) { + $data .= '<'.$t; + } else { + $nsUri = $parts[0]; + $name = $parts[1]; + if (!isset($this->nsp[$nsUri])) { + foreach ($this->nsp as $tmp1 => $tmp2) { + if (strpos($t, $tmp1) === 0) { + $nsUri = $tmp1; + $name = substr($t, strlen($tmp1)); + break; + } + } + } + + $nsp = isset($this->nsp[$nsUri]) ? $this->nsp[$nsUri] : ''; + $data .= $nsp ? '<' . $nsp . ':' . $name : '<' . $name; + /* ns */ + if (!isset($ns[$nsp.'='.$nsUri]) || !$ns[$nsp.'='.$nsUri]) { + $data .= $nsp ? ' xmlns:'.$nsp.'="'.$nsUri.'"' : ' xmlns="'.$nsUri.'"'; + $ns[$nsp.'='.$nsUri] = true; + $s['ns'] = $ns; + } + } + foreach ($a as $k => $v) { + $parts = $this->splitURI($k); + if (count($parts) === 1) { + $data .= ' '.$k.'="'.$v.'"'; + } else { + $nsUri = $parts[0]; + $name = $parts[1]; + $nsp = isset($this->nsp[$nsUri]) ? $this->nsp[$nsUri] : ''; + $data .= $nsp ? ' '.$nsp.':'.$name.'="'.$v.'"' : ' '.$name.'="'.$v.'"' ; + } + } + $data .= '>'; + $s['o_xml_data'] = $data; + $s['o_xml_level'] = isset($s['o_xml_level']) ? $s['o_xml_level'] + 1 : 1; + if ($t == $s['p']) {/* xml container prop */ + $s['p_xml_literal_level'] = isset($s['p_xml_literal_level']) ? $s['p_xml_literal_level'] + 1 : 1; + } + $this->updateS($s); + } + + /** @ignore */ + protected function endState1($t) + { + /* end of doc */ + $this->state = 0; + } + + /** @ignore */ + protected function endState2($t) + { + /* expecting a prop, getting a close */ + if ($s = $this->getParentS()) { + $hasClosingTag = (isset($s['hasClosingTag']) && !$s['hasClosingTag']) ? 0 : 1; + $this->popS(); + $this->state = 5; + if ($s = $this->getParentS()) { + /* new s */ + if (!isset($s['p']) || !$s['p']) { + /* p close after collection|parseType=Resource|node close after p close */ + $this->state = $this->sCount ? 4 : 1; + if (!$hasClosingTag) { + $this->state = 2; + } + } elseif (!$hasClosingTag) { + $this->state = 2; + } + } + } + } + + /** @ignore */ + protected function endState3($t) + { + /* p close */ + $this->state = 2; + } + + /** @ignore */ + protected function endState4($t) + { + /* empty p | pClose after cdata | pClose after collection */ + if ($s = $this->getParentS()) { + $b = isset($s['p_x_base']) && $s['p_x_base'] ? + $s['p_x_base'] : (isset($s['x_base']) ? $s['x_base'] : ''); + if (isset($s['is_coll']) && $s['is_coll']) { + $this->add($s['value'], $this->rdf.'rest', $this->rdf.'nil', $s['type'], 'uri'); + /* back to collection start */ + while ((!isset($s['p']) || ($s['p'] != $t))) { + $subS = $s; + $this->popS(); + $s = $this->getParentS(); + } + /* reification */ + if (isset($s['p_id']) && $s['p_id']) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $subS['value'], + $s['type'], + $subS['type'] + ); + } + unset($s['p']); + $this->updateS($s); + } else { + $dt = isset($s['o_datatype']) ? $s['o_datatype'] : null; + $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? + $s['p_x_lang'] : (isset($s['x_lang']) ? $s['x_lang'] : null); + $o = array('type' => 'literal', 'value' => $s['o_cdata']); + $this->add( + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'], + $dt, + $l + ); + /* reification */ + if (isset($s['p_id']) && $s['p_id']) { + $this->reify( + $b->resolve('#'.$s['p_id']), + $s['value'], + $s['p'], + $o['value'], + $s['type'], + $o['type'], + $dt, + $l + ); + } + unset($s['o_cdata']); + unset($s['o_datatype']); + unset($s['p']); + $this->updateS($s); + } + $this->state = 2; + } + } + + /** @ignore */ + protected function endState5($t) + { + /* p close */ + if ($s = $this->getParentS()) { + unset($s['p']); + $this->updateS($s); + $this->state = 2; + } + } + + /** @ignore */ + protected function endState6($t) + { + if ($s = $this->getParentS()) { + $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? + $s['p_x_lang'] : + (isset($s['x_lang']) ? $s['x_lang'] : null); + $data = $s['o_xml_data']; + $level = $s['o_xml_level']; + if ($level === 0) { + /* pClose */ + $this->add( + $s['value'], + $s['p'], + trim($data, ' '), + $s['type'], + 'literal', + $this->rdf.'XMLLiteral', + $l + ); + unset($s['o_xml_data']); + $this->state = 2; + } else { + $parts = $this->splitURI($t); + if (count($parts) == 1) { + $data .= '</'.$t.'>'; + } else { + $nsUri = $parts[0]; + $name = $parts[1]; + if (!isset($this->nsp[$nsUri])) { + foreach ($this->nsp as $tmp1 => $tmp2) { + if (strpos($t, $tmp1) === 0) { + $nsUri = $tmp1; + $name = substr($t, strlen($tmp1)); + break; + } + } + } + $nsp = isset($this->nsp[$nsUri]) ? $this->nsp[$nsUri] : ''; + $data .= $nsp ? '</'.$nsp.':'.$name.'>' : '</'.$name.'>'; + } + $s['o_xml_data'] = $data; + $s['o_xml_level'] = $level - 1; + if ($t == $s['p']) { + /* xml container prop */ + $s['p_xml_literal_level']--; + } + } + $this->updateS($s); + } + } + + /** @ignore */ + protected function cdataState4($d) + { + if ($s = $this->getParentS()) { + $s['o_cdata'] = isset($s['o_cdata']) ? $s['o_cdata'] . $d : $d; + $this->updateS($s); + } + } + + /** @ignore */ + protected function cdataState6($d) + { + if ($s = $this->getParentS()) { + if (isset($s['o_xml_data']) || preg_match("/[\n\r]/", $d) || trim($d)) { + $d = htmlspecialchars($d, ENT_NOQUOTES); + $s['o_xml_data'] = isset($s['o_xml_data']) ? $s['o_xml_data'] . $d : $d; + } + $this->updateS($s); + } + } + + /** + * Parse an RDF/XML document into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'rdfxml') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_RdfXml does not support: $format" + ); + } + + $this->init($graph, $baseUri); + $this->resetBnodeMap(); + + /* xml parser */ + $this->initXMLParser(); + + /* parse */ + if (!xml_parse($this->xmlParser, $data, false)) { + throw new EasyRdf_Exception( + 'XML error: "' . xml_error_string(xml_get_error_code($this->xmlParser)) . + '" at line ' . xml_get_current_line_number($this->xmlParser) + ); + } + + xml_parser_free($this->xmlParser); + + return $this->tripleCount; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rdfa.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rdfa.php new file mode 100644 index 000000000000..9e7902bacd7e --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Rdfa.php @@ -0,0 +1,710 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2012 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-2012 Nicholas J Humfrey + * Copyright (c) 1997-2006 Aduna (http://www.aduna-software.com/) + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse RDFa 1.1 with no external dependancies. + * + * http://www.w3.org/TR/rdfa-core/ + * + * @package EasyRdf + * @copyright Copyright (c) 2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Rdfa extends EasyRdf_Parser +{ + const XML_NS = 'http://www.w3.org/XML/1998/namespace'; + const RDF_XML_LITERAL = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'; + const TERM_REGEXP = '/^([a-zA-Z_])([0-9a-zA-Z_\.-]*)$/'; + + public $debug = false; + + /** + * Constructor + * + * @return object EasyRdf_Parser_Rdfa + */ + public function __construct() + { + } + + protected function addTriple($resource, $property, $value) + { + if ($this->debug) { + print "Adding triple: $resource -> $property -> ".$value['type'].':'.$value['value']."\n"; + } + $count = $this->graph->add($resource, $property, $value); + $this->tripleCount += $count; + return $count; + } + + protected function generateList($subject, $property, $list) + { + $current = $subject; + $prop = $property; + + // Output a blank node for each item in the list + foreach ($list as $item) { + $newNode = $this->graph->newBNodeId(); + $this->addTriple($current, $prop, array('type' => 'bnode', 'value' => $newNode)); + $this->addTriple($newNode, 'rdf:first', $item); + + $current = $newNode; + $prop = 'rdf:rest'; + } + + // Finally, terminate the list + $this->addTriple( + $current, + $prop, + array('type' => 'uri', 'value' => EasyRdf_Namespace::expand('rdf:nil')) + ); + } + + protected function addToList($listMapping, $property, $value) + { + if ($this->debug) { + print "Adding to list: $property -> ".$value['type'].':'.$value['value']."\n"; + } + + // Create property in the list mapping if it doesn't already exist + if (!isset($listMapping->$property)) { + $listMapping->$property = array(); + } + array_push($listMapping->$property, $value); + } + + protected function printNode($node, $depth) + { + $indent = str_repeat(' ', $depth); + print $indent; + switch($node->nodeType) { + case XML_ELEMENT_NODE: + print 'node'; + break; + case XML_ATTRIBUTE_NODE: + print 'attr'; + break; + case XML_TEXT_NODE: + print 'text'; + break; + case XML_CDATA_SECTION_NODE: + print 'cdata'; + break; + case XML_ENTITY_REF_NODE: + print 'entref'; + break; + case XML_ENTITY_NODE: + print 'entity'; + break; + case XML_PI_NODE: + print 'pi'; + break; + case XML_COMMENT_NODE: + print 'comment'; + break; + case XML_DOCUMENT_NODE: + print 'doc'; + break; + case XML_DOCUMENT_TYPE_NODE: + print 'doctype'; + break; + case XML_HTML_DOCUMENT_NODE: + print 'html'; + break; + default: + throw new EasyRdf_Exception("unknown node type: ".$node->nodeType); + break; + } + print ' '.$node->nodeName."\n"; + + if ($node->hasAttributes()) { + foreach ($node->attributes as $attr) { + print $indent.' '.$attr->nodeName." => ".$attr->nodeValue."\n"; + } + } + } + + protected function guessTimeDatatype($value) + { + if (preg_match("/^-?\d{4}-\d{2}-\d{2}(Z|[\-\+]\d{2}:\d{2})?$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#date'; + } elseif (preg_match("/^\d{2}:\d{2}:\d{2}(Z|[\-\+]\d{2}:\d{2})?$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#time'; + } elseif (preg_match("/^-?\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[\-\+]\d{2}:\d{2})?$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#dateTime'; + } elseif (preg_match("/^P(\d+Y)?(\d+M)?(\d+D)?T?(\d+H)?(\d+M)?(\d+S)?$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#duration'; + } elseif (preg_match("/^\d{4}$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#gYear'; + } elseif (preg_match("/^\d{4}-\d{2}$/", $value)) { + return 'http://www.w3.org/2001/XMLSchema#gYearMonth'; + } else { + return null; + } + } + + protected function initialContext() + { + $context = array( + 'prefixes' => array(), + 'vocab' => null, + 'subject' => $this->baseUri, + 'property' => null, + 'object' => null, + 'terms' => array(), + 'incompleteRels' => array(), + 'incompleteRevs' => array(), + 'listMapping' => null, + 'lang' => null, + 'path' => '', + 'xmlns' => array(), + ); + + // Set the default prefix + $context['prefixes'][''] = 'http://www.w3.org/1999/xhtml/vocab#'; + + // RDFa 1.1 default term mapping + $context['terms']['describedby'] = 'http://www.w3.org/2007/05/powder-s#describedby'; + $context['terms']['license'] = 'http://www.w3.org/1999/xhtml/vocab#license'; + $context['terms']['role'] = 'http://www.w3.org/1999/xhtml/vocab#role'; + + return $context; + } + + protected function expandCurie($node, &$context, $value) + { + if (preg_match("/^(\w*?):(.*)$/", $value, $matches)) { + list (, $prefix, $local) = $matches; + $prefix = strtolower($prefix); + if ($prefix === '_') { + // It is a bnode + return $this->remapBnode(substr($value, 2)); + } elseif (empty($prefix) and $context['vocab']) { + // Empty prefix + return $context['vocab'] . $local; + } elseif (isset($context['prefixes'][$prefix])) { + return $context['prefixes'][$prefix] . $local; + } elseif ($uri = $node->lookupNamespaceURI($prefix)) { + return $uri . $local; + } elseif (!empty($prefix) and $uri = EasyRdf_Namespace::get($prefix)) { + // Expand using well-known prefixes + return $uri . $local; + } + } + } + + protected function processUri($node, &$context, $value, $isProp = false) + { + if (preg_match("/^\[(.*)\]$/", $value, $matches)) { + // Safe CURIE + return $this->expandCurie($node, $context, $matches[1]); + } elseif (preg_match(self::TERM_REGEXP, $value) and $isProp) { + $term = strtolower($value); + if ($context['vocab']) { + return $context['vocab'] . $value; + } elseif (isset($context['terms'][$term])) { + return $context['terms'][$term]; + } + } elseif (substr($value, 0, 2) === '_:' and $isProp) { + return null; + } else { + $uri = $this->expandCurie($node, $context, $value); + if ($uri) { + return $uri; + } else { + $parsed = new EasyRdf_ParsedUri($value); + if ($parsed->isAbsolute()) { + return $value; + } elseif ($isProp) { + // Properties can't be relative URIs + return null; + } elseif ($this->baseUri) { + return $this->baseUri->resolve($parsed); + } + } + } + } + + protected function processUriList($node, $context, $values) + { + if (!$values) { + return array(); + } + + $uris = array(); + foreach (preg_split("/\s+/", $values) as $value) { + $uri = $this->processUri($node, $context, $value, true); + if ($uri) { + array_push($uris, $uri); + } + } + return $uris; + } + + protected function getUriAttribute($node, &$context, $attributes) + { + if (!is_array($attributes)) { + $attributes = array($attributes); + } + + // Find the first attribute that returns a valid URI + foreach ($attributes as $attribute) { + if ($node->hasAttribute($attribute)) { + $value = $node->getAttribute($attribute); + $uri = $this->processUri($node, $context, $value); + if ($uri) { + return $uri; + } + } + } + } + + protected function processNode($node, &$context, $depth = 1) + { + if ($this->debug) { + $this->printNode($node, $depth); + } + + // Step 1: establish local variables + $skip = false; + $subject = null; + $typedResource = null; + $object = null; + $rels = array(); + $revs = array(); + $lang = $context['lang']; + $incompleteRels = array(); + $incompleteRevs = array(); + + if ($node->nodeType === XML_ELEMENT_NODE) { + $context['path'] .= '/' . $node->nodeName; + + $content = $node->hasAttribute('content') ? $node->getAttribute('content') : null; + $datatype = $node->hasAttribute('datatype') ? $node->getAttribute('datatype') : null; + $property = $node->getAttribute('property') ? $node->getAttribute('property') : null; + $typeof = $node->getAttribute('typeof') ? $node->getAttribute('typeof') : null; + + // Step 2: Default vocabulary + if ($node->hasAttribute('vocab')) { + $context['vocab'] = $node->getAttribute('vocab'); + if ($context['vocab']) { + $this->addTriple( + $this->baseUri, + 'rdfa:usesVocabulary', + array('type' => 'uri', 'value' => $context['vocab']) + ); + } + } + + // Step 3: Set prefix mappings + // Support for deprecated xmlns if present in document + foreach ($context['xmlns'] as $prefix => $uri) { + if ($node->hasAttribute('xmlns:' . $prefix)) { + $context['prefixes'][$prefix] = $node->getAttribute('xmlns:' . $prefix); + if ($this->debug) { + print "Prefix (xmlns): $prefix => $uri\n"; + } + } + } + if ($node->hasAttribute('prefix')) { + $mappings = preg_split("/\s+/", $node->getAttribute('prefix')); + while (count($mappings)) { + $prefix = strtolower(array_shift($mappings)); + $uri = array_shift($mappings); + + if (substr($prefix, -1) === ':') { + $prefix = substr($prefix, 0, -1); + } else { + continue; + } + + if ($prefix === '_') { + continue; + } elseif (!empty($prefix)) { + $context['prefixes'][$prefix] = $uri; + if ($this->debug) { + print "Prefix: $prefix => $uri\n"; + } + } + } + } + + // Step 4 + if ($node->hasAttributeNS(self::XML_NS, 'lang')) { + $lang = $node->getAttributeNS(self::XML_NS, 'lang'); + } elseif ($node->hasAttribute('lang')) { + $lang = $node->getAttribute('lang'); + } + + if (!$node->hasAttribute('rel') and !$node->hasAttribute('rev')) { + // Step 5: Establish a new subject if no rel/rev + if ($property and is_null($content) and is_null($datatype)) { + $subject = $this->getUriAttribute($node, $context, 'about'); + if ($typeof and !$subject) { + $typedResource = $this->getUriAttribute( + $node, + $context, + array('resource', 'href', 'src') + ); + if (!$typedResource) { + $typedResource = $this->graph->newBNodeId(); + } + $object = $typedResource; + } + } else { + $subject = $this->getUriAttribute( + $node, + $context, + array('about', 'resource', 'href', 'src') + ); + } + + // Establish a subject if there isn't one + # FIXME: refactor this + if (is_null($subject)) { + if ($context['path'] === '/html/head') { + $subject = $context['object']; + } elseif ($depth <= 2) { + $subject = $this->baseUri; + } elseif ($typeof and !$property) { + $subject = $this->graph->newBNodeId(); + } else { + if (!$property) { + $skip = true; + } + $subject = $context['object']; + } + } + + } else { + // Step 6 + // If the current element does contain a @rel or @rev attribute, then the next step is to + // establish both a value for new subject and a value for current object resource: + + $subject = $this->getUriAttribute($node, $context, 'about'); + + $object = $this->getUriAttribute( + $node, + $context, + array('resource', 'href', 'src') + ); + + if ($typeof) { + if (!$object and !$subject) { + $object = $this->graph->newBNodeId(); + } + $typedResource = $subject ? $subject : $object; + } + + # FIXME: if the element is the root element of the document + # then act as if there is an empty @about present + if (!$subject) { + $subject = $context['object']; + } + + $rels = $this->processUriList($node, $context, $node->getAttribute('rel')); + $revs = $this->processUriList($node, $context, $node->getAttribute('rev')); + } + + # FIXME: better place for this? + if ($typeof and $subject and !$typedResource) { + $typedResource = $subject; + } + + // Step 7: Process @typeof if there is a subject + if ($typedResource) { + foreach ($this->processUriList($node, $context, $typeof) as $type) { + $this->addTriple( + $typedResource, + 'rdf:type', + array('type' => 'uri', 'value' => $type) + ); + } + } + + // Step 8: Create new List mapping if the subject has changed + if ($subject and $subject !== $context['subject']) { + $listMapping = new StdClass(); + } else { + $listMapping = $context['listMapping']; + } + + // Step 9: Generate triples with given object + if ($subject and $object) { + foreach ($rels as $prop) { + $obj = array('type' => 'uri', 'value' => $object); + if ($node->hasAttribute('inlist')) { + $this->addToList($listMapping, $prop, $obj); + } else { + $this->addTriple($subject, $prop, $obj); + } + } + + foreach ($revs as $prop) { + $this->addTriple( + $object, + $prop, + array('type' => 'uri', 'value' => $subject) + ); + } + } elseif ($rels or $revs) { + // Step 10: Incomplete triples and bnode creation + $object = $this->graph->newBNodeId(); + if ($rels) { + if ($node->hasAttribute('inlist')) { + foreach ($rels as $prop) { + # FIXME: add support for incomplete lists + if (!isset($listMapping->$prop)) { + $listMapping->$prop = array(); + } + } + } else { + $incompleteRels = $rels; + if ($this->debug) { + print "Incomplete rels: ".implode(',', $rels)."\n"; + } + } + } + + if ($revs) { + $incompleteRevs = $revs; + if ($this->debug) { + print "Incomplete revs: ".implode(',', $revs)."\n"; + } + } + } + + // Step 11: establish current property value + if ($subject and $property) { + $value = array(); + + if ($datatype) { + $datatype = $this->processUri($node, $context, $datatype, true); + } + + if ($node->nodeName === 'data' and $node->hasAttribute('value')) { + $value['value'] = $node->getAttribute('value'); + } elseif ($node->hasAttribute('datetime')) { + $value['value'] = $node->getAttribute('datetime'); + $datetime = true; + } elseif ($datatype === '') { + $value['value'] = $node->textContent; + } elseif ($datatype === self::RDF_XML_LITERAL) { + $value['value'] = ''; + foreach ($node->childNodes as $child) { + $value['value'] .= $child->C14N(); + } + } elseif ($content !== null) { + $value['value'] = $content; + } elseif (is_null($datatype) and empty($rel) and empty($rev)) { + $value['value'] = $this->getUriAttribute( + $node, + $context, + array('resource', 'href', 'src') + ); + + if ($value['value']) { + $value['type'] = 'uri'; + } + } + + if (empty($value['value']) and $typedResource and !$node->hasAttribute('about')) { + $value['type'] = 'uri'; + $value['value'] = $typedResource; + } + + if (empty($value['value'])) { + $value['value'] = $node->textContent; + } + + if (empty($value['type'])) { + $value['type'] = 'literal'; + if ($datatype) { + $value['datatype'] = $datatype; + } elseif (isset($datetime) or $node->nodeName === 'time') { + $value['datatype'] = $this->guessTimeDatatype($value['value']); + } + + if (empty($value['datatype']) and $lang) { + $value['lang'] = $lang; + } + } + + // Add each of the properties + foreach ($this->processUriList($node, $context, $property) as $prop) { + if ($node->hasAttribute('inlist')) { + $this->addToList($listMapping, $prop, $value); + } elseif ($subject) { + $this->addTriple($subject, $prop, $value); + } + } + } + + // Step 12: Complete the incomplete triples from the evaluation context + if (!$skip and $subject and ($context['incompleteRels'] or $context['incompleteRevs'])) { + foreach ($context['incompleteRels'] as $prop) { + $this->addTriple( + $context['subject'], + $prop, + array('type' => 'uri', 'value' => $subject) + ); + } + + foreach ($context['incompleteRevs'] as $prop) { + $this->addTriple( + $subject, + $prop, + array('type' => 'uri', 'value' => $context['subject']) + ); + } + } + } + + // Step 13: create a new evaluation context and proceed recursively + if ($node->hasChildNodes()) { + if ($skip) { + $newContext = $context; + } else { + // Prepare a new evaluation context + $newContext = $context; + if ($object) { + $newContext['object'] = $object; + } elseif ($subject) { + $newContext['object'] = $subject; + } else { + $newContext['object'] = $context['subject']; + } + if ($subject) { + $newContext['subject'] = $subject; + } + $newContext['incompleteRels'] = $incompleteRels; + $newContext['incompleteRevs'] = $incompleteRevs; + if (isset($listMapping)) { + $newContext['listMapping'] = $listMapping; + } + } + + // The language is always updated, even if skip is set + $newContext['lang'] = $lang; + + foreach ($node->childNodes as $child) { + if ($child->nodeType === XML_ELEMENT_NODE) { + $this->processNode($child, $newContext, $depth+1); + } + } + } + + // Step 14: create triples for lists + if (!empty($listMapping)) { + foreach ($listMapping as $prop => $list) { + if ($context['listMapping'] !== $listMapping) { + if ($this->debug) { + print "Need to create triples for $prop => ".count($list)." items\n"; + } + $this->generateList($subject, $prop, $list); + } + } + } + } + + /** + * Parse RDFa 1.1 into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'rdfa') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_Rdfa does not support: $format" + ); + } + + // Initialise evaluation context. + $context = $this->initialContext(); + + libxml_use_internal_errors(true); + + // Parse the document into DOM + $doc = new DOMDocument(); + // Attempt to parse the document as strict XML, and fall back to HTML + // if XML parsing fails. + if ($doc->loadXML($data, LIBXML_NONET)) { + if ($this->debug) { + print "Document was parsed as XML."; + } + // Collect all xmlns namespaces defined throughout the document. + $sxe = simplexml_import_dom($doc); + $context['xmlns'] = $sxe->getDocNamespaces(true); + unset($context['xmlns']['']); + } else { + $doc->loadHTML($data); + if ($this->debug) { + print "Document was parsed as HTML."; + } + } + + // Establish the base for both XHTML and HTML documents. + $xpath = new DOMXPath($doc); + $xpath->registerNamespace('xh', "http://www.w3.org/1999/xhtml"); + $nodeList = $xpath->query('/xh:html/xh:head/xh:base'); + if ($node = $nodeList->item(0) and $href = $node->getAttribute('href')) { + $this->baseUri = new EasyRdf_ParsedUri($href); + } + $nodeList = $xpath->query('/html/head/base'); + if ($node = $nodeList->item(0) and $href = $node->getAttribute('href')) { + $this->baseUri = new EasyRdf_ParsedUri($href); + } + + // Remove the fragment from the base URI + $this->baseUri->setFragment(null); + + // Recursively process XML nodes + $this->processNode($doc, $context); + + return $this->tripleCount; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Redland.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Redland.php new file mode 100644 index 000000000000..c21c02de8653 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Redland.php @@ -0,0 +1,247 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse RDF using Redland (librdf) C library. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Redland extends EasyRdf_Parser +{ + /** Variable set to the librdf world */ + private $world = null; + + /** Parser feature URI string for getting the error count of last parse. */ + const LIBRDF_PARSER_FEATURE_ERROR_COUNT = + 'http://feature.librdf.org/parser-error-count'; + + /* + * Types supported by Redland: + * + * ntriples: N-Triples + * turtle: Turtle Terse RDF Triple Language + * trig: TriG - Turtle with Named Graphs + * rss-tag-soup: RSS Tag Soup + * grddl: Gleaning Resource Descriptions from Dialects of Languages + * guess: Pick the parser to use using content type and URI + * rdfa: RDF/A via librdfa + * raptor: (null) + * rdfxml: RDF/XML + */ + + + /** + * Convert a librdf node type into a string + * @ignore + */ + protected function nodeTypeString($node) + { + switch(librdf_node_get_type($node)) { + case 1: + return 'uri'; + break; + case 2: + return 'literal'; + break; + case 4: + return 'bnode'; + break; + default: + return 'unknown'; + break; + } + } + + /** + * Convert the URI for a node into a string + * @ignore + */ + protected function nodeUriString($node) + { + $type = EasyRdf_Parser_Redland::nodeTypeString($node); + if ($type == 'uri') { + $uri = librdf_node_get_uri($node); + if (!$uri) { + throw new EasyRdf_Exception("Failed to get URI of node"); + } + $str = librdf_uri_to_string($uri); + if (!$str) { + throw new EasyRdf_Exception( + "Failed to convert librdf_uri to string" + ); + } + return $str; + } elseif ($type == 'bnode') { + return $this->remapBnode( + librdf_node_get_blank_identifier($node) + ); + } else { + throw new EasyRdf_Exception("Unsupported type: ".$type); + } + } + + /** + * Convert a node into an associate array + * @ignore + */ + protected function nodeToArray($node) + { + $object = array(); + $object['type'] = EasyRdf_Parser_Redland::nodeTypeString($node); + if ($object['type'] == 'uri') { + $object['value'] = EasyRdf_Parser_Redland::nodeUriString($node); + } elseif ($object['type'] == 'bnode') { + $object['value'] = '_:'.librdf_node_get_blank_identifier($node); + } elseif ($object['type'] == 'literal') { + $object['value'] = librdf_node_get_literal_value($node); + $lang = librdf_node_get_literal_value_language($node); + if ($lang) { + $object['lang'] = $lang; + } + $datatype = librdf_node_get_literal_value_datatype_uri($node); + if ($datatype) { + $object['datatype'] = librdf_uri_to_string($datatype); + } + } else { + throw new EasyRdf_Exception("Unsupported type: ".$object['type']); + } + return $object; + } + + /** + * Return the number of errors during parsing + * @ignore + */ + protected function parserErrorCount($parser) + { + $errorUri = librdf_new_uri( + $this->world, + self::LIBRDF_PARSER_FEATURE_ERROR_COUNT + ); + $errorNode = librdf_parser_get_feature($parser, $errorUri); + $errorCount = librdf_node_get_literal_value($errorNode); + librdf_free_uri($errorUri); + return $errorCount; + } + + /** + * Constructor + * + * @return object EasyRdf_Parser_Redland + */ + public function __construct() + { + if (extension_loaded('redland')) { + $this->world = librdf_php_get_world(); + if (!$this->world) { + throw new EasyRdf_Exception( + "Failed to initialise librdf world." + ); + } + } else { + throw new EasyRdf_Exception( + "Redland PHP extension is not available." + ); + } + } + + /** + * Parse an RDF document into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + $parser = librdf_new_parser($this->world, $format, null, null); + if (!$parser) { + throw new EasyRdf_Exception( + "Failed to create librdf_parser of type: $format" + ); + } + + $rdfUri = librdf_new_uri($this->world, $baseUri); + if (!$rdfUri) { + throw new EasyRdf_Exception( + "Failed to create librdf_uri from: $baseUri" + ); + } + + $stream = librdf_parser_parse_string_as_stream($parser, $data, $rdfUri); + if (!$stream) { + throw new EasyRdf_Exception( + "Failed to parse RDF stream for: $rdfUri" + ); + } + + do { + $statement = librdf_stream_get_object($stream); + if ($statement) { + $subject = EasyRdf_Parser_Redland::nodeUriString( + librdf_statement_get_subject($statement) + ); + $predicate = EasyRdf_Parser_Redland::nodeUriString( + librdf_statement_get_predicate($statement) + ); + $object = EasyRdf_Parser_Redland::nodeToArray( + librdf_statement_get_object($statement) + ); + + $this->addTriple($subject, $predicate, $object); + } + } while (!librdf_stream_next($stream)); + + $errorCount = $this->parserErrorCount($parser); + if ($errorCount) { + throw new EasyRdf_Exception("$errorCount errors while parsing."); + } + + librdf_free_uri($rdfUri); + librdf_free_stream($stream); + librdf_free_parser($parser); + + return $this->tripleCount; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Turtle.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Turtle.php new file mode 100644 index 000000000000..bbbec479b1de --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Parser/Turtle.php @@ -0,0 +1,1134 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 Nicholas J Humfrey. + * Copyright (c) 1997-2006 Aduna (http://www.aduna-software.com/) + * 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-2012 Nicholas J Humfrey + * Copyright (c) 1997-2006 Aduna (http://www.aduna-software.com/) + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to parse Turtle with no external dependancies. + * + * http://www.w3.org/TR/turtle/ + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * Copyright (c) 1997-2006 Aduna (http://www.aduna-software.com/) + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Parser_Turtle extends EasyRdf_Parser_Ntriples +{ + /** + * Constructor + * + * @return object EasyRdf_Parser_Turtle + */ + public function __construct() + { + } + + /** + * Parse Turtle into an EasyRdf_Graph + * + * @param object EasyRdf_Graph $graph the graph to load the data into + * @param string $data the RDF document data + * @param string $format the format of the input data + * @param string $baseUri the base URI of the data being parsed + * @return integer The number of triples added to the graph + */ + public function parse($graph, $data, $format, $baseUri) + { + parent::checkParseParams($graph, $data, $format, $baseUri); + + if ($format != 'turtle') { + throw new EasyRdf_Exception( + "EasyRdf_Parser_Turtle does not support: $format" + ); + } + + $this->data = $data; + $this->len = strlen($data); + $this->pos = 0; + + $this->namespaces = array(); + $this->subject = null; + $this->predicate = null; + $this->object = null; + + $this->resetBnodeMap(); + + $c = $this->skipWSC(); + while ($c != -1) { + $this->parseStatement(); + $c = $this->skipWSC(); + } + + return $this->tripleCount; + } + + + /** + * Parse a statement [2] + * @ignore + */ + protected function parseStatement() + { + $c = $this->peek(); + if ($c == '@') { + $this->parseDirective(); + $this->skipWSC(); + $this->verifyCharacter($this->read(), "."); + } else { + $this->parseTriples(); + $this->skipWSC(); + $this->verifyCharacter($this->read(), "."); + } + } + + /** + * Parse a directive [3] + * @ignore + */ + protected function parseDirective() + { + // Verify that the first characters form the string "prefix" + $this->verifyCharacter($this->read(), "@"); + + $directive = ''; + + $c = $this->read(); + while ($c != -1 && !self::isWhitespace($c)) { + $directive .= $c; + $c = $this->read(); + } + + if ($directive == "prefix") { + $this->parsePrefixID(); + } elseif ($directive == "base") { + $this->parseBase(); + } elseif (strlen($directive) == 0) { + throw new EasyRdf_Exception( + "Turtle Parse Error: directive name is missing, expected @prefix or @base" + ); + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: unknown directive \"@$directive\"" + ); + } + } + + /** + * Parse a prefixID [4] + * @ignore + */ + protected function parsePrefixID() + { + $this->skipWSC(); + + // Read prefix ID (e.g. "rdf:" or ":") + $prefixID = ''; + + while (true) { + $c = $this->read(); + if ($c == ':') { + $this->unread($c); + break; + } elseif (self::isWhitespace($c)) { + break; + } elseif ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading prefix id" + ); + } + + $prefixID .= $c; + } + + $this->skipWSC(); + $this->verifyCharacter($this->read(), ":"); + $this->skipWSC(); + + // Read the namespace URI + $namespace = $this->parseURI(); + + // Store local namespace mapping + $this->namespaces[$prefixID] = $namespace['value']; + } + + /** + * Parse base [5] + * @ignore + */ + protected function parseBase() + { + $this->skipWSC(); + + $baseUri = $this->parseURI(); + $this->baseUri = new EasyRdf_ParsedUri($baseUri['value']); + } + + /** + * Parse triples [6] + * @ignore + */ + protected function parseTriples() + { + $this->parseSubject(); + $this->skipWSC(); + $this->parsePredicateObjectList(); + + $this->subject = null; + $this->predicate = null; + $this->object = null; + } + + /** + * Parse a predicateObjectList [7] + * @ignore + */ + protected function parsePredicateObjectList() + { + $this->predicate = $this->parsePredicate(); + + $this->skipWSC(); + $this->parseObjectList(); + + while ($this->skipWSC() == ';') { + $this->read(); + + $c = $this->skipWSC(); + + if ($c == '.' || $c == ']') { + break; + } + + $this->predicate = $this->parsePredicate(); + + $this->skipWSC(); + + $this->parseObjectList(); + } + } + + /** + * Parse a objectList [8] + * @ignore + */ + protected function parseObjectList() + { + $this->parseObject(); + + while ($this->skipWSC() == ',') { + $this->read(); + $this->skipWSC(); + $this->parseObject(); + } + } + + /** + * Parse a subject [10] + * @ignore + */ + protected function parseSubject() + { + $c = $this->peek(); + if ($c == '(') { + $this->subject = $this->parseCollection(); + } elseif ($c == '[') { + $this->subject = $this->parseImplicitBlank(); + } else { + $value = $this->parseValue(); + + if ($value['type'] == 'uri' or $value['type'] == 'bnode') { + $this->subject = $value; + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: illegal subject type: ".$value['type'] + ); + } + } + } + + /** + * Parse a predicate [11] + * @ignore + */ + protected function parsePredicate() + { + // Check if the short-cut 'a' is used + $c1 = $this->read(); + + if ($c1 == 'a') { + $c2 = $this->read(); + + if (self::isWhitespace($c2)) { + // Short-cut is used, return the rdf:type URI + return array( + 'type' => 'uri', + 'value' => EasyRdf_Namespace::get('rdf') . 'type' + ); + } + + // Short-cut is not used, unread all characters + $this->unread($c2); + } + $this->unread($c1); + + // Predicate is a normal resource + $predicate = $this->parseValue(); + if ($predicate['type'] == 'uri') { + return $predicate; + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: Illegal predicate value: " . $predicate + ); + } + } + + /** + * Parse a object [12] + * @ignore + */ + protected function parseObject() + { + $c = $this->peek(); + + if ($c == '(') { + $this->object = $this->parseCollection(); + } elseif ($c == '[') { + $this->object = $this->parseImplicitBlank(); + } else { + $this->object = $this->parseValue(); + } + + $this->addTriple( + $this->subject['value'], + $this->predicate['value'], + $this->object + ); + } + + /** + * Parses a blankNodePropertyList [15] + * + * This method parses the token [] + * and predicateObjectLists that are surrounded by square brackets. + * + * @ignore + */ + protected function parseImplicitBlank() + { + $this->verifyCharacter($this->read(), "["); + + $bnode = array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId() + ); + + $c = $this->read(); + if ($c != ']') { + $this->unread($c); + + // Remember current subject and predicate + $oldSubject = $this->subject; + $oldPredicate = $this->predicate; + + // generated bNode becomes subject + $this->subject = $bnode; + + // Enter recursion with nested predicate-object list + $this->skipWSC(); + + $this->parsePredicateObjectList(); + + $this->skipWSC(); + + // Read closing bracket + $this->verifyCharacter($this->read(), "]"); + + // Restore previous subject and predicate + $this->subject = $oldSubject; + $this->predicate = $oldPredicate; + } + + return $bnode; + } + + /** + * Parses a collection [16], e.g: ( item1 item2 item3 ) + * @ignore + */ + protected function parseCollection() + { + $this->verifyCharacter($this->read(), "("); + + $c = $this->skipWSC(); + if ($c == ')') { + // Empty list + $this->read(); + return array( + 'type' => 'uri', + 'value' => EasyRdf_Namespace::get('rdf') . 'nil' + ); + } else { + $listRoot = array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId() + ); + + // Remember current subject and predicate + $oldSubject = $this->subject; + $oldPredicate = $this->predicate; + + // generated bNode becomes subject, predicate becomes rdf:first + $this->subject = $listRoot; + $this->predicate = array( + 'type' => 'uri', + 'value' => EasyRdf_Namespace::get('rdf') . 'first' + ); + + $this->parseObject(); + $bNode = $listRoot; + + while ($this->skipWSC() != ')') { + // Create another list node and link it to the previous + $newNode = array( + 'type' => 'bnode', + 'value' => $this->graph->newBNodeId() + ); + + $this->addTriple( + $bNode['value'], + EasyRdf_Namespace::get('rdf') . 'rest', + $newNode + ); + + // New node becomes the current + $this->subject = $bNode = $newNode; + + $this->parseObject(); + } + + // Skip ')' + $this->read(); + + // Close the list + $this->addTriple( + $bNode['value'], + EasyRdf_Namespace::get('rdf') . 'rest', + array( + 'type' => 'uri', + 'value' => EasyRdf_Namespace::get('rdf') . 'nil' + ) + ); + + // Restore previous subject and predicate + $this->subject = $oldSubject; + $this->predicate = $oldPredicate; + + return $listRoot; + } + } + + /** + * Parses an RDF value. This method parses uriref, qname, node ID, quoted + * literal, integer, double and boolean. + * @ignore + */ + protected function parseValue() + { + $c = $this->peek(); + + if ($c == '<') { + // uriref, e.g. <foo://bar> + return $this->parseURI(); + } elseif ($c == ':' || self::isPrefixStartChar($c)) { + // qname or boolean + return $this->parseQNameOrBoolean(); + } elseif ($c == '_') { + // node ID, e.g. _:n1 + return $this->parseNodeID(); + } elseif ($c == '"' or $c == "'") { + // quoted literal, e.g. "foo" or """foo""" or 'foo' or '''foo''' + return $this->parseQuotedLiteral($c); + } elseif (ctype_digit($c) || $c == '.' || $c == '+' || $c == '-') { + // integer or double, e.g. 123 or 1.2e3 + return $this->parseNumber(); + } elseif ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading value" + ); + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: expected an RDF value here, found '$c'" + ); + } + } + + /** + * Parses a quoted string, optionally followed by a language tag or datatype. + * @param string $quote The type of quote to use (either ' or ") + * @ignore + */ + protected function parseQuotedLiteral($quote) + { + $label = $this->parseQuotedString($quote); + + // Check for presence of a language tag or datatype + $c = $this->peek(); + + if ($c == '@') { + $this->read(); + + // Read language + $lang = ''; + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading language" + ); + } elseif (!self::isLanguageStartChar($c)) { + throw new EasyRdf_Exception( + "Turtle Parse Error: expected a letter, found '$c'" + ); + } + + $lang .= $c; + + $c = $this->read(); + while (self::isLanguageChar($c)) { + $lang .= $c; + $c = $this->read(); + } + + $this->unread($c); + + return array( + 'type' => 'literal', + 'value' => $label, + 'lang' => $lang + ); + } elseif ($c == '^') { + $this->read(); + + // next character should be another '^' + $this->verifyCharacter($this->read(), "^"); + + // Read datatype + $datatype = $this->parseValue(); + if ($datatype['type'] == 'uri') { + return array( + 'type' => 'literal', + 'value' => $label, + 'datatype' => $datatype['value'] + ); + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: illegal datatype value: $datatype" + ); + } + } else { + return array( + 'type' => 'literal', + 'value' => $label + ); + } + } + + /** + * Parses a quoted string, which is either a "normal string" or a """long string""". + * @param string $quote The type of quote to use (either ' or ") + * @ignore + */ + protected function parseQuotedString($quote) + { + $result = null; + + // First character should be ' or " + $this->verifyCharacter($this->read(), $quote); + + // Check for long-string, which starts and ends with three double quotes + $c2 = $this->read(); + $c3 = $this->read(); + + if ($c2 == $quote && $c3 == $quote) { + // Long string + $result = $this->parseLongString($quote); + } else { + // Normal string + $this->unread($c3); + $this->unread($c2); + + $result = $this->parseString($quote); + } + + // Unescape any escape sequences + return $this->unescapeString($result); + } + + /** + * Parses a "normal string". This method assumes that the first double quote + * has already been parsed. + * @param string $quote The type of quote to use (either ' or ") + * @ignore + */ + protected function parseString($quote) + { + $str = ''; + + while (true) { + $c = $this->read(); + + if ($c == $quote) { + break; + } elseif ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading string" + ); + } + + $str .= $c; + + if ($c == '\\') { + // This escapes the next character, which might be a ' or a " + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading string" + ); + } + $str .= $c; + } + } + + return $str; + } + + /** + * Parses a """long string""". This method assumes that the first three + * double quotes have already been parsed. + * @param string $quote The type of quote to use (either ' or ") + * @ignore + */ + protected function parseLongString($quote) + { + $str = ''; + $doubleQuoteCount = 0; + + while ($doubleQuoteCount < 3) { + $c = $this->read(); + + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading long string" + ); + } elseif ($c == $quote) { + $doubleQuoteCount++; + } else { + $doubleQuoteCount = 0; + } + + $str .= $c; + + if ($c == '\\') { + // This escapes the next character, which might be a ' or " + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading long string" + ); + } + $str .= $c; + } + } + + return substr($str, 0, -3); + } + + /** + * Parses a numeric value, either of type integer, decimal or double + * @ignore + */ + protected function parseNumber() + { + $value = ''; + $datatype = EasyRdf_Namespace::get('xsd').'integer'; + + $c = $this->read(); + + // read optional sign character + if ($c == '+' || $c == '-') { + $value .= $c; + $c = $this->read(); + } + + while (ctype_digit($c)) { + $value .= $c; + $c = $this->read(); + } + + if ($c == '.' || $c == 'e' || $c == 'E') { + // We're parsing a decimal or a double + $datatype = EasyRdf_Namespace::get('xsd').'decimal'; + + // read optional fractional digits + if ($c == '.') { + $value .= $c; + $c = $this->read(); + while (ctype_digit($c)) { + $value .= $c; + $c = $this->read(); + } + + if (strlen($value) == 1) { + // We've only parsed a '.' + throw new EasyRdf_Exception( + "Turtle Parse Error: object for statement missing" + ); + } + } else { + if (strlen($value) == 0) { + // We've only parsed an 'e' or 'E' + throw new EasyRdf_Exception( + "Turtle Parse Error: object for statement missing" + ); + } + } + + // read optional exponent + if ($c == 'e' || $c == 'E') { + $datatype = EasyRdf_Namespace::get('xsd').'double'; + $value .= $c; + + $c = $this->read(); + if ($c == '+' || $c == '-') { + $value .= $c; + $c = $this->read(); + } + + if (!ctype_digit($c)) { + throw new EasyRdf_Exception( + "Turtle Parse Error: Exponent value missing" + ); + } + + $value .= $c; + + $c = $this->read(); + while (ctype_digit($c)) { + $value .= $c; + $c = $this->read(); + } + } + } + + // Unread last character, it isn't part of the number + $this->unread($c); + + // Return result as a typed literal + return array( + 'type' => 'literal', + 'value' => $value, + 'datatype' => $datatype + ); + } + + /** + * Parses a URI / IRI + * @ignore + */ + protected function parseURI() + { + $uri = ''; + + // First character should be '<' + $this->verifyCharacter($this->read(), "<"); + + // Read up to the next '>' character + while (true) { + $c = $this->read(); + + if ($c == '>') { + break; + } elseif ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading URI" + ); + } + + $uri .= $c; + + if ($c == '\\') { + // This escapes the next character, which might be a '>' + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading URI" + ); + } + $uri .= $c; + } + } + + // Unescape any escape sequences + $uri = $this->unescapeString($uri); + + return array( + 'type' => 'uri', + 'value' => $this->resolve($uri) + ); + } + + /** + * Parses qnames and boolean values, which have equivalent starting + * characters. + * @ignore + */ + protected function parseQNameOrBoolean() + { + // First character should be a ':' or a letter + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while readying value" + ); + } + if ($c != ':' && !self::isPrefixStartChar($c)) { + throw new EasyRdf_Exception( + "Turtle Parse Error: expected a ':' or a letter, found '$c'" + ); + } + + $namespace = null; + + if ($c == ':') { + // qname using default namespace + $namespace = $this->namespaces[""]; + if ($namespace == null) { + throw new EasyRdf_Exception( + "Turtle Parse Error: default namespace used but not defined" + ); + } + } else { + // $c is the first letter of the prefix + $prefix = $c; + + $c = $this->read(); + while (self::isPrefixChar($c)) { + $prefix .= $c; + $c = $this->read(); + } + + if ($c != ':') { + // prefix may actually be a boolean value + $value = $prefix; + + if ($value == "true" || $value == "false") { + return array( + 'type' => 'literal', + 'value' => $value, + 'datatype' => EasyRdf_Namespace::get('xsd') . 'boolean' + ); + } + } + + $this->verifyCharacter($c, ":"); + + if (isset($this->namespaces[$prefix])) { + $namespace = $this->namespaces[$prefix]; + } else { + throw new EasyRdf_Exception( + "Turtle Parse Error: namespace prefix '$prefix' used but not defined" + ); + } + } + + // $c == ':', read optional local name + $localName = ''; + $c = $this->read(); + if (self::isNameStartChar($c)) { + $localName .= $c; + + $c = $this->read(); + while (self::isNameChar($c)) { + $localName .= $c; + $c = $this->read(); + } + } + + // Unread last character + $this->unread($c); + + // Note: namespace has already been resolved + return array( + 'type' => 'uri', + 'value' => $namespace . $localName + ); + } + + /** + * Parses a blank node ID, e.g: _:node1 + * @ignore + */ + protected function parseNodeID() + { + // Node ID should start with "_:" + $this->verifyCharacter($this->read(), "_"); + $this->verifyCharacter($this->read(), ":"); + + // Read the node ID + $c = $this->read(); + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file while reading node id" + ); + } elseif (!self::isNameStartChar($c)) { + throw new EasyRdf_Exception( + "Turtle Parse Error: expected a letter, found '$c'" + ); + } + + // Read all following letter and numbers, they are part of the name + $name = $c; + $c = $this->read(); + while (self::isNameChar($c)) { + $name .= $c; + $c = $this->read(); + } + + $this->unread($c); + + return array( + 'type' => 'bnode', + 'value' => $this->remapBnode($name) + ); + } + + protected function resolve($uri) + { + if ($this->baseUri) { + return $this->baseUri->resolve($uri)->toString(); + } else { + return $uri; + } + } + + /** + * Verifies that the supplied character $c is one of the expected + * characters specified in $expected. This method will throw a + * exception if this is not the case. + * @ignore + */ + protected function verifyCharacter($c, $expected) + { + if ($c == -1) { + throw new EasyRdf_Exception( + "Turtle Parse Error: unexpected end of file" + ); + } elseif (strpbrk($c, $expected) === false) { + $msg = 'expected '; + for ($i = 0; $i < strlen($expected); $i++) { + if ($i > 0) { + $msg .= " or "; + } + $msg .= '\''.$expected[$i].'\''; + } + $msg .= ", found '$c'"; + + throw new EasyRdf_Exception("Turtle Parse Error: $msg"); + } + } + + /** + * Skip through whitespace and comments + * @ignore + */ + protected function skipWSC() + { + $c = $this->read(); + while (self::isWhitespace($c) || $c == '#') { + if ($c == '#') { + $this->skipLine(); + } + + $c = $this->read(); + } + + $this->unread($c); + return $c; + } + + /** + * Consumes characters from reader until the first EOL has been read. + * @ignore + */ + protected function skipLine() + { + $c = $this->read(); + while ($c != -1 && $c != "\r" && $c != "\n") { + $c = $this->read(); + } + + // c is equal to -1, \r or \n. + // In case c is equal to \r, we should also read a following \n. + if ($c == "\r") { + $c = $this->read(); + if ($c != "\n") { + $this->unread($c); + } + } + } + + /** + * Read a single character from the input buffer. + * Returns -1 when the end of the file is reached. + * @ignore + */ + protected function read() + { + if ($this->pos < $this->len) { + $c = $this->data[$this->pos]; + $this->pos++; + return $c; + } else { + return -1; + } + } + + /** + * Gets the next character to be returned by read() + * without removing it from the input buffer. + * @ignore + */ + protected function peek() + { + if ($this->pos < $this->len) { + return $this->data[$this->pos]; + } else { + return -1; + } + } + + + /** + * Steps back, restoring the previous character read() to the input buffer + * @ignore + */ + protected function unread() + { + if ($this->pos > 0) { + $this->pos--; + } else { + throw new EasyRdf_Exception("Turtle Parse Error: unread error"); + } + } + + /** + * Returns true if $c is a whitespace character + * @ignore + */ + public static function isWhitespace($c) + { + // Whitespace character are space, tab, newline and carriage return: + return $c == " " || $c == "\t" || $c == "\r" || $c == "\n"; + } + + /** @ignore */ + public static function isPrefixStartChar($c) + { + $o = ord($c); + return + $o >= 0x41 && $o <= 0x5a || # A-Z + $o >= 0x61 && $o <= 0x7a || # a-z + $o >= 0x00C0 && $o <= 0x00D6 || + $o >= 0x00D8 && $o <= 0x00F6 || + $o >= 0x00F8 && $o <= 0x02FF || + $o >= 0x0370 && $o <= 0x037D || + $o >= 0x037F && $o <= 0x1FFF || + $o >= 0x200C && $o <= 0x200D || + $o >= 0x2070 && $o <= 0x218F || + $o >= 0x2C00 && $o <= 0x2FEF || + $o >= 0x3001 && $o <= 0xD7FF || + $o >= 0xF900 && $o <= 0xFDCF || + $o >= 0xFDF0 && $o <= 0xFFFD || + $o >= 0x10000 && $o <= 0xEFFFF; + } + + /** @ignore */ + public static function isNameStartChar($c) + { + return $c == '_' || self::isPrefixStartChar($c); + } + + /** @ignore */ + public static function isNameChar($c) + { + $o = ord($c); + return + self::isNameStartChar($c) || + $c == '-' || + $o >= 0x30 && $o <= 0x39 || # numeric + $o == 0x00B7 || + $o >= 0x0300 && $o <= 0x036F || + $o >= 0x203F && $o <= 0x2040; + } + + /** @ignore */ + public static function isPrefixChar($c) + { + return self::isNameChar($c); + } + + /** @ignore */ + public static function isLanguageStartChar($c) + { + $o = ord($c); + return + $o >= 0x41 && $o <= 0x5a || + $o >= 0x61 && $o <= 0x7a; + } + + /** @ignore */ + public static function isLanguageChar($c) + { + $o = ord($c); + return + $o >= 0x41 && $o <= 0x5a || # A-Z + $o >= 0x61 && $o <= 0x7a || # a-z + $o >= 0x30 && $o <= 0x39 || # 0-9 + $c == '-'; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Resource.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Resource.php new file mode 100644 index 000000000000..ee99fbc0b4dc --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Resource.php @@ -0,0 +1,692 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class that represents an RDF resource + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Resource +{ + /** The URI for this resource */ + private $uri = null; + + /** The Graph that this resource belongs to */ + private $graph = null; + + + /** Constructor + * + * * Please do not call new EasyRdf_Resource() directly * + * + * To create a new resource use the get method in a graph: + * $resource = $graph->resource('http://www.example.com/'); + * + */ + public function __construct($uri, $graph = null) + { + if (!is_string($uri) or $uri == null or $uri == '') { + throw new InvalidArgumentException( + "\$uri should be a string and cannot be null or empty" + ); + } + + $this->uri = $uri; + + # Check that $graph is an EasyRdf_Graph object + if (is_object($graph) and $graph instanceof EasyRdf_Graph) { + $this->graph = $graph; + } elseif (!is_null($graph)) { + throw new InvalidArgumentException( + "\$graph should be an EasyRdf_Graph object" + ); + } + } + + /** Returns the URI for the resource. + * + * @return string URI of this resource. + */ + public function getUri() + { + return $this->uri; + } + + /** Check to see if a resource is a blank node. + * + * @return bool True if this resource is a blank node. + */ + public function isBnode() + { + if (substr($this->uri, 0, 2) == '_:') { + return true; + } else { + return false; + } + } + + /** Get the identifier for a blank node + * + * Returns null if the resource is not a blank node. + * + * @return string The identifer for the bnode + */ + public function getNodeId() + { + if (substr($this->uri, 0, 2) == '_:') { + return substr($this->uri, 2); + } else { + return null; + } + } + + /** Get a the prefix of the namespace that this resource is part of + * + * This method will return null the resource isn't part of any + * registered namespace. + * + * @return string The namespace prefix of the resource (e.g. foaf) + */ + public function prefix() + { + return EasyRdf_Namespace::prefixOfUri($this->uri); + } + + /** Get a shortened version of the resources URI. + * + * This method will return the full URI if the resource isn't part of any + * registered namespace. + * + * @return string The shortened URI of this resource (e.g. foaf:name) + */ + public function shorten() + { + return EasyRdf_Namespace::shorten($this->uri); + } + + /** Gets the local name of the URI of this resource + * + * The local name is defined as the part of the URI string + * after the last occurrence of the '#', ':' or '/' character. + * + * @return string The local name + */ + public function localName() + { + if (preg_match("|([^#:/]+)$|", $this->uri, $matches)) { + return $matches[1]; + } + } + + /** Parse the URI of the resource and return as a ParsedUri object + * + * @return EasyRdf_ParsedUri + */ + public function parseUri() + { + return new EasyRdf_ParsedUri($this->uri); + } + + /** Generates an HTML anchor tag, linking to this resource. + * + * If no text is given, then the URI also uses as the link text. + * + * @param string $text Text for the link. + * @param array $options Associative array of attributes for the anchor tag + * @return string The HTML link string + */ + public function htmlLink($text = null, $options = array()) + { + $options = array_merge(array('href' => $this->uri), $options); + if ($text === null) { + $text = $this->uri; + } + + $html = "<a"; + foreach ($options as $key => $value) { + $html .= " ".htmlspecialchars($key)."=\"". + htmlspecialchars($value)."\""; + } + $html .= ">".htmlspecialchars($text)."</a>"; + + return $html; + } + + /** Returns the properties of the resource as an associative array + * + * For example: + * array('type' => 'uri', 'value' => 'http://www.example.com/') + * + * @return array The properties of the resource + */ + public function toArray() + { + if ($this->isBnode()) { + return array('type' => 'bnode', 'value' => $this->uri); + } else { + return array('type' => 'uri', 'value' => $this->uri); + } + } + + /** Return pretty-print view of the resource + * + * @param bool $html Set to true to format the dump using HTML + * @param string $color The colour of the text + * @return string + */ + public function dumpValue($html = true, $color = 'blue') + { + return EasyRdf_Utils::dumpResourceValue($this, $html, $color); + } + + /** Magic method to return URI of resource when casted to string + * + * @return string The URI of the resource + */ + public function __toString() + { + return $this->uri; + } + + + + /** Throw can exception if the resource does not belong to a graph + * @ignore + */ + protected function checkHasGraph() + { + if (!$this->graph) { + throw new EasyRdf_Exception( + "EasyRdf_Resource is not part of a graph." + ); + } + } + + /** Perform a load (download of remote URI) of the resource into the graph + * + * The document type is optional but should be specified if it + * can't be guessed or got from the HTTP headers. + * + * @param string $format Optional format of the data (eg. rdfxml) + */ + public function load($format = null) + { + $this->checkHasGraph(); + return $this->graph->load($this->uri, $format); + } + + /** Delete a property (or optionally just a specific value) + * + * @param string $property The name of the property (e.g. foaf:name) + * @param object $value The value to delete (null to delete all values) + * @return null + */ + public function delete($property, $value = null) + { + $this->checkHasGraph(); + return $this->graph->delete($this->uri, $property, $value); + } + + /** Add values to for a property of the resource + * + * Example: + * $resource->add('prefix:property', 'value'); + * + * @param mixed $property The property name + * @param mixed $value The value for the property + * @return integer The number of values added (1 or 0) + */ + public function add($property, $value) + { + $this->checkHasGraph(); + return $this->graph->add($this->uri, $property, $value); + } + + /** Add a literal value as a property of the resource + * + * The value can either be a single value or an array of values. + * + * Example: + * $resource->add('dc:title', 'Title of Page'); + * + * @param mixed $property The property name + * @param mixed $values The value or values for the property + * @param string $lang The language of the literal + * @return integer The number of values added + */ + public function addLiteral($property, $values, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->addLiteral($this->uri, $property, $values, $lang); + } + + /** Add a resource as a property of the resource + * + * Example: + * $bob->add('foaf:knows', 'http://example.com/alice'); + * + * @param mixed $property The property name + * @param mixed $resource2 The resource to be the value of the property + * @return integer The number of values added (1 or 0) + */ + public function addResource($property, $resource2) + { + $this->checkHasGraph(); + return $this->graph->addResource($this->uri, $property, $resource2); + } + + /** Set value for a property + * + * The new value(s) will replace the existing values for the property. + * The name of the property should be a string. + * If you set a property to null or an empty array, then the property + * will be deleted. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param mixed $value The value for the property. + * @return integer The number of values added (1 or 0) + */ + public function set($property, $value) + { + $this->checkHasGraph(); + return $this->graph->set($this->uri, $property, $value); + } + + /** Get a single value for a property + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * If $property is an array, then the first item in the array that matches + * a property that exists is returned. + * + * This method will return null if the property does not exist. + * + * @param string|array $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal or resource) + * @param string $lang The language to filter by (e.g. en) + * @return mixed A value associated with the property + */ + public function get($property, $type = null, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->get($this->uri, $property, $type, $lang); + } + + /** Get a single literal value for a property of the resource + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * This method will return null if there is not literal value for the + * property. + * + * @param string|array $property The name of the property (e.g. foaf:name) + * @param string $lang The language to filter by (e.g. en) + * @return object EasyRdf_Literal Literal value associated with the property + */ + public function getLiteral($property, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->get($this->uri, $property, 'literal', $lang); + } + + /** Get a single resource value for a property of the resource + * + * If multiple values are set for a property then the value returned + * may be arbitrary. + * + * This method will return null if there is not resource for the + * property. + * + * @param string|array $property The name of the property (e.g. foaf:name) + * @return object EasyRdf_Resource Resource associated with the property + */ + public function getResource($property) + { + $this->checkHasGraph(); + return $this->graph->get($this->uri, $property, 'resource'); + } + + /** Get all values for a property + * + * This method will return an empty array if the property does not exist. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal) + * @param string $lang The language to filter by (e.g. en) + * @return array An array of values associated with the property + */ + public function all($property, $type = null, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->all($this->uri, $property, $type, $lang); + } + + /** Get all literal values for a property of the resource + * + * This method will return an empty array if the resource does not + * has any literal values for that property. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param string $lang The language to filter by (e.g. en) + * @return array An array of values associated with the property + */ + public function allLiterals($property, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->all($this->uri, $property, 'literal', $lang); + } + + /** Get all resources for a property of the resource + * + * This method will return an empty array if the resource does not + * has any resources for that property. + * + * @param string $property The name of the property (e.g. foaf:name) + * @return array An array of values associated with the property + */ + public function allResources($property) + { + $this->checkHasGraph(); + return $this->graph->all($this->uri, $property, 'resource'); + } + + /** Count the number of values for a property of a resource + * + * This method will return 0 if the property does not exist. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param string $type The type of value to filter by (e.g. literal) + * @param string $lang The language to filter by (e.g. en) + * @return integer The number of values associated with the property + */ + public function count($property, $type = null, $lang = null) + { + $this->checkHasGraph(); + return $this->graph->count($this->uri, $property, $type, $lang); + } + + /** Concatenate all values for a property into a string. + * + * The default is to join the values together with a space character. + * This method will return an empty string if the property does not exist. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param string $glue The string to glue the values together with. + * @param string $lang The language to filter by (e.g. en) + * @return string Concatenation of all the values. + */ + public function join($property, $glue = ' ', $lang = null) + { + $this->checkHasGraph(); + return $this->graph->join($this->uri, $property, $glue, $lang); + } + + /** Get a list of the full URIs for the properties of this resource. + * + * This method will return an empty array if the resource has no properties. + * + * @return array Array of full URIs + */ + public function propertyUris() + { + $this->checkHasGraph(); + return $this->graph->propertyUris($this->uri); + } + + /** Get a list of all the shortened property names (qnames) for a resource. + * + * This method will return an empty array if the resource has no properties. + * + * @return array Array of shortened URIs + */ + public function properties() + { + $this->checkHasGraph(); + return $this->graph->properties($this->uri); + } + + /** Get a list of the full URIs for the properties that point to this resource. + * + * @return array Array of full property URIs + */ + public function reversePropertyUris() + { + $this->checkHasGraph(); + return $this->graph->reversePropertyUris($this->uri); + } + + /** Check to see if a property exists for this resource. + * + * This method will return true if the property exists. + * If the value parameter is given, then it will only return true + * if the value also exists for that property. + * + * @param string $property The name of the property (e.g. foaf:name) + * @param mixed $value An optional value of the property + * @return bool True if value the property exists. + */ + public function hasProperty($property, $value = null) + { + $this->checkHasGraph(); + return $this->graph->hasProperty($this->uri, $property, $value); + } + + /** Get a list of types for a resource. + * + * The types will each be a shortened URI as a string. + * This method will return an empty array if the resource has no types. + * + * @return array All types assocated with the resource (e.g. foaf:Person) + */ + public function types() + { + $this->checkHasGraph(); + return $this->graph->types($this->uri); + } + + /** Get a single type for a resource. + * + * The type will be a shortened URI as a string. + * If the resource has multiple types then the type returned + * may be arbitrary. + * This method will return null if the resource has no type. + * + * @return string A type assocated with the resource (e.g. foaf:Person) + */ + public function type() + { + $this->checkHasGraph(); + return $this->graph->type($this->uri); + } + + /** Get a single type for a resource, as a resource. + * + * The type will be returned as an EasyRdf_Resource. + * If the resource has multiple types then the type returned + * may be arbitrary. + * This method will return null if the resource has no type. + * + * @return EasyRdf_Resource A type assocated with the resource. + */ + public function typeAsResource() + { + return $this->graph->typeAsResource($this->uri); + } + + /** Check if a resource is of the specified type + * + * @param string $type The type to check (e.g. foaf:Person) + * @return boolean True if resource is of specified type. + */ + public function isA($type) + { + $this->checkHasGraph(); + return $this->graph->isA($this->uri, $type); + } + + /** Add one or more rdf:type properties to the resource + * + * @param string $types One or more types to add (e.g. foaf:Person) + * @return integer The number of types added + */ + public function addType($types) + { + $this->checkHasGraph(); + return $this->graph->addType($this->uri, $types); + } + + /** Change the rdf:type property for the resource + * + * Note that the PHP class of the resource will not change. + * + * @param string $type The new type (e.g. foaf:Person) + * @return integer The number of types added + */ + public function setType($type) + { + $this->checkHasGraph(); + return $this->graph->setType($this->uri, $type); + } + + /** Get the primary topic of this resource. + * + * Returns null if no primary topic is available. + * + * @return EasyRdf_Resource The primary topic of this resource. + */ + public function primaryTopic() + { + $this->checkHasGraph(); + return $this->graph->primaryTopic($this->uri); + } + + /** Get a human readable label for this resource + * + * This method will check a number of properties for the resource + * (in the order: skos:prefLabel, rdfs:label, foaf:name, dc:title) + * and return an approriate first that is available. If no label + * is available then it will return null. + * + * @return string A label for the resource. + */ + public function label($lang = null) + { + $this->checkHasGraph(); + return $this->graph->label($this->uri, $lang); + } + + /** Return a human readable view of the resource and its properties + * + * This method is intended to be a debugging aid and will + * print a resource and its properties. + * + * @param bool $html Set to true to format the dump using HTML + * @return string + */ + public function dump($html = true) + { + $this->checkHasGraph(); + return $this->graph->dumpResource($this->uri, $html); + } + + /** Magic method to get a property of a resource + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * $value = $resource->title; + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + * @return string A single value for the named property + */ + public function __get($name) + { + return $this->graph->get($this->uri, $name); + } + + /** Magic method to set the value for a property of a resource + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * $resource->title = 'Title'; + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + * @param string $value The value for the property + */ + public function __set($name, $value) + { + return $this->graph->set($this->uri, $name, $value); + } + + /** Magic method to check if a property exists + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * if (isset($resource->title)) { blah(); } + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + */ + public function __isset($name) + { + return $this->graph->hasProperty($this->uri, $name); + } + + /** Magic method to delete a property of the resource + * + * Note that only properties in the default namespace can be accessed in this way. + * + * Example: + * unset($resource->title); + * + * @see EasyRdf_Namespace::setDefault() + * @param string $name The name of the property + */ + public function __unset($name) + { + return $this->graph->delete($this->uri, $name); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser.php new file mode 100644 index 000000000000..19467faf7579 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser.php @@ -0,0 +1,115 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Parent class for the EasyRdf serialiser + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser +{ + protected $prefixes = array(); + + /** + * Keep track of the prefixes used while serialising + * @ignore + */ + protected function addPrefix($qname) + { + list ($prefix) = explode(':', $qname); + $this->prefixes[$prefix] = true; + } + + /** + * Check and cleanup parameters passed to serialise() method + * @ignore + */ + protected function checkSerialiseParams(&$graph, &$format) + { + if ($graph == null or !is_object($graph) or + get_class($graph) != 'EasyRdf_Graph') { + throw new InvalidArgumentException( + "\$graph should be an EasyRdf_Graph object and cannot be null" + ); + } + + if ($format == null or $format == '') { + throw new InvalidArgumentException( + "\$format cannot be null or empty" + ); + } elseif (is_object($format) and + get_class($format) == 'EasyRdf_Format') { + $format = $format->getName(); + } elseif (!is_string($format)) { + throw new InvalidArgumentException( + "\$format should be a string or an EasyRdf_Format object" + ); + } + } + + /** + * Protected method to get the number of reverse properties for a resource + * If a resource only has a single property, the number of values for that + * property is returned instead. + * @ignore + */ + protected function reversePropertyCount($resource) + { + $properties = $resource->reversePropertyUris(); + $count = count($properties); + if ($count == 1) { + $property = $properties[0]; + return $resource->count("^<$property>"); + } else { + return $count; + } + } + + /** + * Sub-classes must follow this protocol + * @ignore + */ + public function serialise($graph, $format) + { + throw new EasyRdf_Exception( + "This method should be overridden by sub-classes." + ); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Arc.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Arc.php new file mode 100644 index 000000000000..fc79eca1a84d --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Arc.php @@ -0,0 +1,97 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise RDF using the ARC2 library. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_Arc extends EasyRdf_Serialiser_RdfPhp +{ + private static $supportedTypes = array( + 'rdfxml' => 'RDFXML', + 'turtle' => 'Turtle', + 'ntriples' => 'NTriples', + 'posh' => 'POSHRDF' + ); + + /** + * Constructor + * + * @return object EasyRdf_Serialiser_Arc + */ + public function __construct() + { + require_once 'arc/ARC2.php'; + } + + /** + * Serialise an EasyRdf_Graph into RDF format of choice. + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if (array_key_exists($format, self::$supportedTypes)) { + $className = self::$supportedTypes[$format]; + } else { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_Arc does not support: $format" + ); + } + + $serialiser = ARC2::getSer($className); + if ($serialiser) { + return $serialiser->getSerializedIndex( + parent::serialise($graph, 'php') + ); + } else { + throw new EasyRdf_Exception( + "ARC2 failed to get a $className serialiser." + ); + } + } +} + +EasyRdf_Format::register('posh', 'poshRDF'); diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/GraphViz.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/GraphViz.php new file mode 100644 index 000000000000..632f932729d9 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/GraphViz.php @@ -0,0 +1,391 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to GraphViz + * + * Depends upon the GraphViz 'dot' command line tools to render images. + * + * See http://www.graphviz.org/ for more information. + * + * @package EasyRdf + * @copyright Copyright (c) 2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_GraphViz extends EasyRdf_Serialiser +{ + private $dotCommand = 'dot'; + private $useLabels = false; + private $onlyLabelled = false; + private $attributes = array('charset' => 'utf-8'); + + /** + * Constructor + * + * @return object EasyRdf_Serialiser_GraphViz + */ + public function __construct() + { + } + + /** + * Set the path to the GraphViz 'dot' command + * + * Default is to search PATH for the command 'dot'. + * + * @param string $cmd The path to the 'dot' command. + * @return object EasyRdf_Serialiser_GraphViz + */ + public function setDotCommand($cmd) + { + $this->dotCommand = $cmd; + return $this; + } + + /** + * Get the path to the GraphViz 'dot' command + * + * The default value is simply 'dot' + * + * @return string The path to the 'dot' command. + */ + public function getDotCommand() + { + return $this->dotCommand; + } + + /** + * Turn on/off the option to display labels instead of URIs. + * + * When this option is turned on, then labels for resources will + * be displayed instead of the full URI of a resource. This makes + * it simpler to create friendly diagrams that non-technical people + * can understand. + * + * This option is turned off by default. + * + * @param bool $useLabels A boolean value to turn labels on and off + * @return object EasyRdf_Serialiser_GraphViz + */ + public function setUseLabels($useLabels) + { + $this->useLabels = $useLabels; + return $this; + } + + /** + * Get the state of the use labels option + * + * @return bool The current state of the use labels option + */ + public function getUseLabels() + { + return $this->useLabels; + } + + /** + * Turn on/off the option to only display nodes and edges with labels + * + * When this option is turned on, then only nodes (resources and literals) + * and edges (properties) will only be displayed if they have a label. You + * can use this option, to create concise, diagrams of your data, rather than + * the RDF. + * + * This option is turned off by default. + * + * @param bool $onlyLabelled A boolean value to enable/display only labelled items + * @return object EasyRdf_Serialiser_GraphViz + */ + public function setOnlyLabelled($onlyLabelled) + { + $this->onlyLabelled = $onlyLabelled; + return $this; + } + + /** + * Get the state of the only Only Labelled option + * + * @return bool The current state of the Only Labelled option + */ + public function getOnlyLabelled() + { + return $this->onlyLabelled; + } + + /** + * Set an attribute on the GraphViz graph + * + * Example: + * $serialiser->setAttribute('rotate', 90); + * + * See the GraphViz tool documentation for information about the + * available attributes. + * + * @param string $name The name of the attribute + * @param string $value The value for the attribute + * @return object EasyRdf_Serialiser_GraphViz + */ + public function setAttribute($name, $value) + { + $this->attributes[$name] = $value; + return $this; + } + + /** + * Get an attribute of the GraphViz graph + * + * @param string $name Attribute name + * @return string The value of the graph attribute + */ + public function getAttribute($name) + { + return $this->attributes[$name]; + } + + /** + * Convert an EasyRdf object into a GraphViz node identifier + * + * @ignore + */ + protected function nodeName($entity) + { + if ($entity instanceof EasyRdf_Resource) { + if ($entity->isBnode()) { + return "B".$entity->getUri(); + } else { + return "R".$entity->getUri(); + } + } else { + return "L".$entity; + } + } + + /** + * Internal function to escape a string into DOT safe syntax + * + * @ignore + */ + protected function escape($input) + { + if (preg_match('/^([a-z_][a-z_0-9]*|-?(\.[0-9]+|[0-9]+(\.[0-9]*)?))$/i', $input)) { + return $input; + } else { + return '"'.str_replace( + array("\r\n", "\n", "\r", '"'), + array('\n', '\n', '\n', '\"'), + $input + ).'"'; + } + } + + /** + * Internal function to escape an associate array of attributes and + * turns it into a DOT notation string + * + * @ignore + */ + protected function escapeAttributes($array) + { + $items = ''; + foreach ($array as $k => $v) { + $items[] = $this->escape($k).'='.$this->escape($v); + } + return '['.implode(',', $items).']'; + } + + /** + * Internal function to create dot syntax line for either a node or an edge + * + * @ignore + */ + protected function serialiseRow($node1, $node2 = null, $attributes = array()) + { + $result = ' '.$this->escape($node1); + if ($node2) { + $result .= ' -> '.$this->escape($node2); + } + if (count($attributes)) { + $result .= ' '.$this->escapeAttributes($attributes); + } + return $result.";\n"; + } + + /** + * Internal function to serialise an EasyRdf_Graph into a DOT formatted string + * + * @ignore + */ + protected function serialiseDot($graph) + { + $result = "digraph {\n"; + + // Write the graph attributes + foreach ($this->attributes as $k => $v) { + $result .= ' '.$this->escape($k).'='.$this->escape($v).";\n"; + } + + // Go through each of the properties and write the edges + $nodes = array(); + $result .= "\n // Edges\n"; + foreach ($graph->resources() as $resource) { + $name1 = $this->nodeName($resource); + foreach ($resource->propertyUris() as $property) { + $label = null; + if ($this->useLabels) { + $label = $graph->resource($property)->label(); + } + if ($label === null) { + if ($this->onlyLabelled == true) { + continue; + } else { + $label = EasyRdf_Namespace::shorten($property); + } + } + foreach ($resource->all("<$property>") as $value) { + $name2 = $this->nodeName($value); + $nodes[$name1] = $resource; + $nodes[$name2] = $value; + $result .= $this->serialiseRow( + $name1, + $name2, + array('label' => $label) + ); + } + } + } + + ksort($nodes); + + $result .= "\n // Nodes\n"; + foreach ($nodes as $name => $node) { + $type = substr($name, 0, 1); + $label = ''; + if ($type == 'R') { + if ($this->useLabels) { + $label = $node->label(); + } + if (!$label) { + $label = $node->shorten(); + } + if (!$label) { + $label = $node->getURI(); + } + $result .= $this->serialiseRow( + $name, + null, + array( + 'URL' => $node->getURI(), + 'label' => $label, + 'shape' => 'ellipse', + 'color' => 'blue' + ) + ); + } elseif ($type == 'B') { + if ($this->useLabels) { + $label = $node->label(); + } + $result .= $this->serialiseRow( + $name, + null, + array( + 'label' => $label, + 'shape' => 'circle', + 'color' => 'green' + ) + ); + } else { + $result .= $this->serialiseRow( + $name, + null, + array( + 'label' => strval($node), + 'shape' => 'record', + ) + ); + } + + } + + $result .= "}\n"; + + return $result; + } + + /** + * Internal function to render a graph into an image + * + * @ignore + */ + public function renderImage($graph, $format = 'png') + { + $dot = $this->serialiseDot($graph); + + return EasyRdf_Utils::execCommandPipe( + $this->dotCommand, + array("-T$format"), + $dot + ); + } + + /** + * Serialise an EasyRdf_Graph into a GraphViz dot document. + * + * Supported output format names: dot, gif, png, svg + * + * @param string $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + switch($format) { + case 'dot': + return $this->serialiseDot($graph); + case 'png': + case 'gif': + case 'svg': + return $this->renderImage($graph, $format); + default: + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_GraphViz does not support: $format" + ); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Json.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Json.php new file mode 100644 index 000000000000..d2bc15ea699e --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Json.php @@ -0,0 +1,70 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to RDF/JSON + * with no external dependancies. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_Json extends EasyRdf_Serialiser_RdfPhp +{ + /** + * Method to serialise an EasyRdf_Graph to RDF/JSON + * + * http://n2.talis.com/wiki/RDF_JSON_Specification + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if ($format != 'json') { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_Json does not support: $format" + ); + } + + return json_encode(parent::serialise($graph, 'php')); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Ntriples.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Ntriples.php new file mode 100644 index 000000000000..02577511e793 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Ntriples.php @@ -0,0 +1,209 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to N-Triples + * with no external dependancies. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_Ntriples extends EasyRdf_Serialiser +{ + private $escChars = array(); // Character encoding cache + + /** + * @ignore + */ + protected function escapeString($str) + { + if (strpos(utf8_decode(str_replace('?', '', $str)), '?') === false) { + $str = utf8_decode($str); + } + + $result = ''; + $strLen = strlen($str); + for ($i = 0; $i < $strLen; $i++) { + $c = $str[$i]; + if (!isset($this->escChars[$c])) { + $this->escChars[$c] = $this->escapedChar($c); + } + $result .= $this->escChars[$c]; + } + return $result; + } + + /** + * @ignore + */ + protected function unicodeCharNo($c) + { + $cUtf = utf8_encode($c); + $bl = strlen($cUtf); /* binary length */ + $r = 0; + switch ($bl) { + case 1: /* 0####### (0-127) */ + $r = ord($cUtf); + break; + case 2: /* 110##### 10###### = 192+x 128+x */ + $r = ((ord($cUtf[0]) - 192) * 64) + + (ord($cUtf[1]) - 128); + break; + case 3: /* 1110#### 10###### 10###### = 224+x 128+x 128+x */ + $r = ((ord($cUtf[0]) - 224) * 4096) + + ((ord($cUtf[1]) - 128) * 64) + + (ord($cUtf[2]) - 128); + break; + case 4: /* 1111#### 10###### 10###### 10###### = 240+x 128+x 128+x 128+x */ + $r = ((ord($cUtf[0]) - 240) * 262144) + + ((ord($cUtf[1]) - 128) * 4096) + + ((ord($cUtf[2]) - 128) * 64) + + (ord($cUtf[3]) - 128); + break; + } + return $r; + } + + /** + * @ignore + */ + protected function escapedChar($c) + { + $no = $this->unicodeCharNo($c); + + /* see http://www.w3.org/TR/rdf-testcases/#ntrip_strings */ + if ($no < 9) { + return "\\u" . sprintf('%04X', $no); /* #x0-#x8 (0-8) */ + } elseif ($no == 9) { + return '\t'; /* #x9 (9) */ + } elseif ($no == 10) { + return '\n'; /* #xA (10) */ + } elseif ($no < 13) { + return "\\u" . sprintf('%04X', $no); /* #xB-#xC (11-12) */ + } elseif ($no == 13) { + return '\r'; /* #xD (13) */ + } elseif ($no < 32) { + return "\\u" . sprintf('%04X', $no); /* #xE-#x1F (14-31) */ + } elseif ($no < 34) { + return $c; /* #x20-#x21 (32-33) */ + } elseif ($no == 34) { + return '\"'; /* #x22 (34) */ + } elseif ($no < 92) { + return $c; /* #x23-#x5B (35-91) */ + } elseif ($no == 92) { + return '\\'; /* #x5C (92) */ + } elseif ($no < 127) { + return $c; /* #x5D-#x7E (93-126) */ + } elseif ($no < 65536) { + return "\\u" . sprintf('%04X', $no); /* #x7F-#xFFFF (128-65535) */ + } elseif ($no < 1114112) { + return "\\U" . sprintf('%08X', $no); /* #x10000-#x10FFFF (65536-1114111) */ + } else { + return ''; /* not defined => ignore */ + } + } + + /** + * @ignore + */ + protected function ntriplesResource($res) + { + $escaped = $this->escapeString($res); + if (substr($res, 0, 2) == '_:') { + return $escaped; + } else { + return "<$escaped>"; + } + } + + /** + * @ignore + */ + protected function ntriplesValue($value) + { + if ($value['type'] == 'uri' or $value['type'] == 'bnode') { + return $this->ntriplesResource($value['value']); + } elseif ($value['type'] == 'literal') { + $escaped = $this->escapeString($value['value']); + if (isset($value['lang'])) { + $lang = $this->escapeString($value['lang']); + return '"' . $escaped . '"' . '@' . $lang; + } elseif (isset($value['datatype'])) { + $datatype = $this->escapeString($value['datatype']); + return '"' . $escaped . '"' . "^^<$datatype>"; + } else { + return '"' . $escaped . '"'; + } + } else { + throw new EasyRdf_Exception( + "Unable to serialise object to ntriples: ".$value['type'] + ); + } + } + + /** + * Serialise an EasyRdf_Graph into N-Triples + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if ($format == 'ntriples') { + $nt = ''; + foreach ($graph->toArray() as $resource => $properties) { + foreach ($properties as $property => $values) { + foreach ($values as $value) { + $nt .= $this->ntriplesResource($resource)." "; + $nt .= "<" . $this->escapeString($property) . "> "; + $nt .= $this->ntriplesValue($value)." .\n"; + } + } + } + return $nt; + } else { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_Ntriples does not support: $format" + ); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Rapper.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Rapper.php new file mode 100644 index 000000000000..a23b6c30ed37 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Rapper.php @@ -0,0 +1,100 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to RDF + * using the 'rapper' command line tool. + * + * Note: the built-in N-Triples serialiser is used to pass data to Rapper. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_Rapper extends EasyRdf_Serialiser_Ntriples +{ + private $rapperCmd = null; + + /** + * Constructor + * + * @param string $rapperCmd Optional path to the rapper command to use. + * @return object EasyRdf_Serialiser_Rapper + */ + public function __construct($rapperCmd = 'rapper') + { + $result = exec("$rapperCmd --version 2>/dev/null", $output, $status); + if ($status != 0) { + throw new EasyRdf_Exception( + "Failed to execute the command '$rapperCmd': $result" + ); + } else { + $this->rapperCmd = $rapperCmd; + } + } + + /** + * Serialise an EasyRdf_Graph to the RDF format of choice. + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + $ntriples = parent::serialise($graph, 'ntriples'); + + // Hack to produce more concise RDF/XML + if ($format == 'rdfxml') { + $format = 'rdfxml-abbrev'; + } + + return EasyRdf_Utils::execCommandPipe( + $this->rapperCmd, + array( + '--quiet', + '--input', 'ntriples', + '--output', $format, + '-', 'unknown://' + ), + $ntriples + ); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfPhp.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfPhp.php new file mode 100644 index 000000000000..e6a864704b35 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfPhp.php @@ -0,0 +1,71 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to RDF/PHP + * with no external dependancies. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_RdfPhp extends EasyRdf_Serialiser +{ + /** + * Method to serialise an EasyRdf_Graph to RDF/PHP + * + * http://n2.talis.com/wiki/RDF_PHP_Specification + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if ($format != 'php') { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_RdfPhp does not support: $format" + ); + } + + // Graph is already stored an RDF/PHP resource-centric array internally within the EasyRdf_Graph object + return $graph->toArray(); + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfXml.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfXml.php new file mode 100644 index 000000000000..1936d8f62dc6 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/RdfXml.php @@ -0,0 +1,218 @@ +<?php +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to RDF/XML + * with no external dependancies. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_RdfXml extends EasyRdf_Serialiser +{ + private $outputtedResources = array(); + + /** A constant for the RDF Type property URI */ + const RDF_XML_LITERAL = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral'; + + /** + * Protected method to serialise an object node into an XML object + * @ignore + */ + protected function rdfxmlObject($property, $obj, $depth) + { + $indent = str_repeat(' ', $depth); + if (is_object($obj) and $obj instanceof EasyRdf_Resource) { + $pcount = count($obj->propertyUris()); + $rpcount = $this->reversePropertyCount($obj); + $alreadyOutput = isset($this->outputtedResources[$obj->getUri()]); + + $tag = "$indent<$property"; + if ($obj->isBNode()) { + if ($alreadyOutput or $rpcount > 1 or $pcount == 0) { + $tag .= " rdf:nodeID=\"".htmlspecialchars($obj->getNodeId()).'"'; + } + } else { + if ($alreadyOutput or $rpcount != 1 or $pcount == 0) { + $tag .= " rdf:resource=\"".htmlspecialchars($obj->getURI()).'"'; + } + } + + if ($alreadyOutput == false and $rpcount == 1 and $pcount > 0) { + $xml = $this->rdfxmlResource($obj, false, $depth+1); + if ($xml) { + return "$tag>$xml$indent</$property>\n\n"; + } else { + return ''; + } + } else { + return $tag."/>\n"; + } + + } elseif (is_object($obj) and $obj instanceof EasyRdf_Literal) { + $atrributes = ""; + $datatype = $obj->getDatatypeUri(); + if ($datatype) { + if ($datatype == self::RDF_XML_LITERAL) { + $atrributes .= " rdf:parseType=\"Literal\""; + $value = strval($obj); + } else { + $datatype = htmlspecialchars($datatype); + $atrributes .= " rdf:datatype=\"$datatype\""; + } + } elseif ($obj->getLang()) { + $atrributes .= ' xml:lang="'. + htmlspecialchars($obj->getLang()).'"'; + } + + // Escape the value + if (!isset($value)) { + $value = htmlspecialchars(strval($obj)); + } + + return "$indent<$property$atrributes>$value</$property>\n"; + } else { + throw new EasyRdf_Exception( + "Unable to serialise object to xml: ".getType($obj) + ); + } + } + + /** + * Protected method to serialise a whole resource and its properties + * @ignore + */ + protected function rdfxmlResource($res, $showNodeId, $depth = 1) + { + // Keep track of the resources we have already serialised + if (isset($this->outputtedResources[$res->getUri()])) { + return ''; + } else { + $this->outputtedResources[$res->getUri()] = true; + } + + // If the resource has no properties - don't serialise it + $properties = $res->propertyUris(); + if (count($properties) == 0) { + return ''; + } + + $type = $res->type(); + if ($type) { + $this->addPrefix($type); + } else { + $type = 'rdf:Description'; + } + + $indent = str_repeat(' ', $depth); + $xml = "\n$indent<$type"; + if ($res->isBNode()) { + if ($showNodeId) { + $xml .= ' rdf:nodeID="'.htmlspecialchars($res->getNodeId()).'"'; + } + } else { + $xml .= ' rdf:about="'.htmlspecialchars($res->getUri()).'"'; + } + $xml .= ">\n"; + + foreach ($properties as $property) { + $short = EasyRdf_Namespace::shorten($property, true); + if ($short) { + $this->addPrefix($short); + $objects = $res->all("<$property>"); + if ($short == 'rdf:type') { + array_shift($objects); + } + foreach ($objects as $object) { + $xml .= $this->rdfxmlObject($short, $object, $depth+1); + } + } else { + throw new EasyRdf_Exception( + "It is not possible to serialse the property ". + "'$property' to RDF/XML." + ); + } + } + $xml .= "$indent</$type>\n"; + + return $xml; + } + + + /** + * Method to serialise an EasyRdf_Graph to RDF/XML + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if ($format != 'rdfxml') { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_RdfXml does not support: $format" + ); + } + + // store of namespaces to be appended to the rdf:RDF tag + $this->prefixes = array('rdf' => true); + + // store of the resource URIs we have serialised + $this->outputtedResources = array(); + + $xml = ''; + foreach ($graph->resources() as $resource) { + $xml .= $this->rdfxmlResource($resource, true, 1); + } + + // iterate through namepsaces array prefix and output a string. + $namespaceStr = ''; + foreach ($this->prefixes as $prefix => $count) { + $url = EasyRdf_Namespace::get($prefix); + if (strlen($namespaceStr)) { + $namespaceStr .= "\n "; + } + $namespaceStr .= ' xmlns:'.$prefix.'="'.htmlspecialchars($url).'"'; + } + + return "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n". + "<rdf:RDF". $namespaceStr . ">\n" . $xml . "\n</rdf:RDF>\n"; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Turtle.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Turtle.php new file mode 100644 index 000000000000..dfc817d9b818 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Serialiser/Turtle.php @@ -0,0 +1,266 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to serialise an EasyRdf_Graph to Turtle + * with no external dependancies. + * + * http://www.dajobe.org/2004/01/turtle + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Serialiser_Turtle extends EasyRdf_Serialiser +{ + private $outputtedBnodes = array(); + + /** + * @ignore + */ + protected function serialiseResource($resource) + { + if ($resource->isBnode()) { + return $resource->getUri(); + } else { + $short = $resource->shorten(); + if ($short) { + $this->addPrefix($short); + return $short; + } else { + $uri = str_replace('>', '\\>', $resource); + return "<$resource>"; + } + } + } + + /** + * @ignore + */ + protected function quotedString($value) + { + if (preg_match("/[\t\n\r]/", $value)) { + $escaped = str_replace(array('\\', '"""'), array('\\\\', '\\"""'), $value); + return '"""'.$escaped.'"""'; + } else { + $escaped = str_replace(array('\\', '"'), array('\\\\', '\\"'), $value); + return '"'.$escaped.'"'; + } + } + + /** + * @ignore + */ + protected function serialiseObject($object) + { + if ($object instanceof EasyRdf_Resource) { + return $this->serialiseResource($object); + } else { + $value = strval($object); + $quoted = $this->quotedString($value); + + if ($datatype = $object->getDatatypeUri()) { + $short = EasyRdf_Namespace::shorten($datatype, true); + if ($short) { + $this->addPrefix($short); + if ($short == 'xsd:integer') { + return sprintf('%d', $value); + } elseif ($short == 'xsd:decimal') { + return sprintf('%g', $value); + } elseif ($short == 'xsd:double') { + return sprintf('%e', $value); + } elseif ($short == 'xsd:boolean') { + return sprintf('%s', $value ? 'true' : 'false'); + } else { + return sprintf('%s^^%s', $quoted, $short); + } + } else { + $datatypeUri = str_replace('>', '\\>', $datatype); + return sprintf('%s^^<%s>', $quoted, $datatypeUri); + } + } elseif ($lang = $object->getLang()) { + return $quoted . '@' . $lang; + } else { + return $quoted; + } + } + } + + /** + * Protected method to serialise the properties of a resource + * @ignore + */ + protected function serialiseProperties($res, $depth = 1) + { + $properties = $res->propertyUris(); + $indent = str_repeat(' ', ($depth*2)-1); + + $turtle = ''; + if (count($properties) > 1) { + $turtle .= "\n$indent"; + } + + $pCount = 0; + foreach ($properties as $property) { + $short = EasyRdf_Namespace::shorten($property, true); + if ($short) { + if ($short == 'rdf:type') { + $pStr = 'a'; + } else { + $this->addPrefix($short); + $pStr = $short; + } + } else { + $pStr = '<'.str_replace('>', '\\>', $property).'>'; + } + + if ($pCount) { + $turtle .= " ;\n$indent"; + } + + $turtle .= ' ' . $pStr; + + $oCount = 0; + foreach ($res->all("<$property>") as $object) { + if ($oCount) { + $turtle .= ','; + } + + if ($object instanceof EasyRdf_Resource and $object->isBnode()) { + $id = $object->getNodeId(); + $rpcount = $this->reversePropertyCount($object); + if ($rpcount <= 1 and !isset($this->outputtedBnodes[$id])) { + // Nested unlabelled Blank Node + $this->outputtedBnodes[$id] = true; + $turtle .= ' ['; + $turtle .= $this->serialiseProperties($object, $depth+1); + $turtle .= ' ]'; + } else { + // Multiple properties pointing to this blank node + $turtle .= ' ' . $this->serialiseObject($object); + } + } else { + $turtle .= ' ' . $this->serialiseObject($object); + } + $oCount++; + } + $pCount++; + } + + if ($depth == 1) { + $turtle .= " ."; + if ($pCount > 1) { + $turtle .= "\n"; + } + } elseif ($pCount > 1) { + $turtle .= "\n" . str_repeat(' ', (($depth-1)*2)-1); + } + + return $turtle; + } + + /** + * @ignore + */ + protected function serialisePrefixes() + { + $turtle = ''; + foreach ($this->prefixes as $prefix => $count) { + $url = EasyRdf_Namespace::get($prefix); + $turtle .= "@prefix $prefix: <$url> .\n"; + } + return $turtle; + } + + /** + * Serialise an EasyRdf_Graph to Turtle. + * + * @param object EasyRdf_Graph $graph An EasyRdf_Graph object. + * @param string $format The name of the format to convert to. + * @return string The RDF in the new desired format. + */ + public function serialise($graph, $format) + { + parent::checkSerialiseParams($graph, $format); + + if ($format != 'turtle' and $format != 'n3') { + throw new EasyRdf_Exception( + "EasyRdf_Serialiser_Turtle does not support: $format" + ); + } + + $this->prefixes = array(); + $this->outputtedBnodes = array(); + + $turtle = ''; + foreach ($graph->resources() as $resource) { + // If the resource has no properties - don't serialise it + $properties = $resource->propertyUris(); + if (count($properties) == 0) { + continue; + } + + if ($resource->isBnode()) { + $id = $resource->getNodeId(); + $rpcount = $this->reversePropertyCount($resource); + if (isset($this->outputtedBnodes[$id])) { + // Already been serialised + continue; + } else { + $this->outputtedBnodes[$id] = true; + if ($rpcount == 0) { + $turtle .= '[]'; + } else { + $turtle .= $this->serialiseResource($resource); + } + } + } else { + $turtle .= $this->serialiseResource($resource); + } + + $turtle .= $this->serialiseProperties($resource); + $turtle .= "\n"; + } + + if (count($this->prefixes)) { + return $this->serialisePrefixes() . "\n" . $turtle; + } else { + return $turtle; + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Client.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Client.php new file mode 100644 index 000000000000..35eca3da7231 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Client.php @@ -0,0 +1,134 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class for making SPARQL queries using the SPARQL 1.1 Protocol + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Sparql_Client +{ + /** The address of the SPARQL Endpoint */ + private $uri = null; + + /** Configuration settings */ + private $config = array(); + + + /** Create a new SPARQL endpoint client + * + * @param string $uri The address of the SPARQL Endpoint + */ + public function __construct($uri) + { + $this->uri = $uri; + } + + /** Get the URI of the SPARQL endpoint + * + * @return string The URI of the SPARQL endpoint + */ + public function getUri() + { + return $this->uri; + } + + /** Make a query to the SPARQL endpoint + * + * SELECT and ASK queries will return an object of type + * EasyRdf_Sparql_Result. + * + * CONSTRUCT and DESCRIBE queries will return an object + * of type EasyRdf_Graph. + * + * @param string $query The query string to be executed + * @return object EasyRdf_Sparql_Result|EasyRdf_Graph Result of the query. + */ + public function query($query) + { + # Add namespaces to the queryString + $prefixes = ''; + foreach (EasyRdf_Namespace::namespaces() as $prefix => $uri) { + if (strpos($query, "$prefix:") !== false and + strpos($query, "PREFIX $prefix:") === false) { + $prefixes .= "PREFIX $prefix: <$uri>\n"; + } + } + + $client = EasyRdf_Http::getDefaultHttpClient(); + $client->resetParameters(); + $client->setUri($this->uri); + $client->setMethod('GET'); + + $accept = EasyRdf_Format::getHttpAcceptHeader( + array( + 'application/sparql-results+json' => 1.0, + 'application/sparql-results+xml' => 0.8 + ) + ); + $client->setHeaders('Accept', $accept); + $client->setParameterGet('query', $prefixes . $query); + + $response = $client->request(); + if ($response->isSuccessful()) { + list($type, $params) = EasyRdf_Utils::parseMimeType( + $response->getHeader('Content-Type') + ); + if (strpos($type, 'application/sparql-results') === 0) { + return new EasyRdf_Sparql_Result($response->getBody(), $type); + } else { + return new EasyRdf_Graph($this->uri, $response->getBody(), $type); + } + } else { + throw new EasyRdf_Exception( + "HTTP request for SPARQL query failed: ".$response->getBody() + ); + } + } + + /** Magic method to return URI of the SPARQL endpoint when casted to string + * + * @return string The URI of the SPARQL endpoint + */ + public function __toString() + { + return $this->uri == null ? '' : $this->uri; + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Result.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Result.php new file mode 100644 index 000000000000..6bc7f62aae52 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Sparql/Result.php @@ -0,0 +1,381 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class for returned for SPARQL SELECT and ASK query responses. + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2012 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 bool $html Set to true to format the dump using HTML + */ + public function dump($html = true) + { + if ($this->type == 'bindings') { + $result = ''; + if ($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) { + $result .= "<td style='border:solid 1px #000;padding:4px;". + "vertical-align:top'>". + $row->$field->dumpValue($html)."</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(false); + $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 ($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(false); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/TypeMapper.php b/core/vendor/njh/easyrdf/lib/EasyRdf/TypeMapper.php new file mode 100644 index 000000000000..b2deaf074993 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/TypeMapper.php @@ -0,0 +1,116 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2010 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-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + +/** + * Class to map between RDF Types and PHP Classes + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_TypeMapper +{ + /** The type map registry */ + private static $map = array(); + + /** Get the registered class for an RDF type + * + * If a type is not registered, then this method will return null. + * + * @param string $type The RDF type (e.g. foaf:Person) + * @return string The class name (e.g. Model_Foaf_Name) + */ + public static function get($type) + { + if (!is_string($type) or $type == null or $type == '') { + throw new InvalidArgumentException( + "\$type should be a string and cannot be null or empty" + ); + } + + $type = EasyRdf_Namespace::expand($type); + if (array_key_exists($type, self::$map)) { + return self::$map[$type]; + } else { + return null; + } + } + + /** Register an RDF type with a PHP Class name + * + * @param string $type The RDF type (e.g. foaf:Person) + * @param string $class The PHP class name (e.g. Model_Foaf_Name) + * @return string The PHP class name + */ + public static function set($type, $class) + { + if (!is_string($type) or $type == null or $type == '') { + throw new InvalidArgumentException( + "\$type should be a string and cannot be null or empty" + ); + } + + if (!is_string($class) or $class == null or $class == '') { + throw new InvalidArgumentException( + "\$class should be a string and cannot be null or empty" + ); + } + + $type = EasyRdf_Namespace::expand($type); + return self::$map[$type] = $class; + } + + /** + * Delete an existing RDF type mapping. + * + * @param string $type The RDF type (e.g. foaf:Person) + */ + public static function delete($type) + { + if (!is_string($type) or $type == null or $type == '') { + throw new InvalidArgumentException( + "\$type should be a string and cannot be null or empty" + ); + } + + $type = EasyRdf_Namespace::expand($type); + if (isset(self::$map[$type])) { + unset(self::$map[$type]); + } + } +} diff --git a/core/vendor/njh/easyrdf/lib/EasyRdf/Utils.php b/core/vendor/njh/easyrdf/lib/EasyRdf/Utils.php new file mode 100644 index 000000000000..a48686b7cf58 --- /dev/null +++ b/core/vendor/njh/easyrdf/lib/EasyRdf/Utils.php @@ -0,0 +1,276 @@ +<?php + +/** + * EasyRdf + * + * LICENSE + * + * Copyright (c) 2009-2012 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-2012 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + * @version $Id$ + */ + + +/** + * Class containing static utility functions + * + * @package EasyRdf + * @copyright Copyright (c) 2009-2010 Nicholas J Humfrey + * @license http://www.opensource.org/licenses/bsd-license.php + */ +class EasyRdf_Utils +{ + + /** + * Convert a string into CamelCase + * + * A capital letter is inserted for any non-letter (including userscore). + * For example: + * 'hello world' becomes HelloWorld + * 'rss-tag-soup' becomes RssTagSoup + * 'FOO//BAR' becomes FooBar + * + * @param string The input string + * @return string The input string converted to CamelCase + */ + public static function camelise($str) + { + $cc = ''; + foreach (preg_split("/[\W_]+/", $str) as $part) { + $cc .= ucfirst(strtolower($part)); + } + return $cc; + } + + /** + * Check if something is an associative array + * + * Note: this method only checks the key of the first value in the array. + * + * @param mixed $param The variable to check + * @return bool true if the variable is an associative array + */ + public static function isAssociativeArray($param) + { + if (is_array($param)) { + $keys = array_keys($param); + if ($keys[0] === 0) { + return false; + } else { + return true; + } + } else { + return false; + } + } + + /** + * Remove the fragment from a URI (if it has one) + * + * @param mixed $uri A URI + * @return string The same URI with the fragment removed + */ + public static function removeFragmentFromUri($uri) + { + $pos = strpos($uri, '#'); + if ($pos === false) { + return $uri; + } else { + return substr($uri, 0, $pos); + } + } + + /** Return pretty-print view of a resource URI + * + * This method is mainly intended for internal use and is used by + * EasyRdf_Graph and EasyRdf_Sparql_Result to format a resource + * for display. + * + * @param mixed $resource An EasyRdf_Resource object or an associative array + * @param bool $html Set to true to format the dump using HTML + * @param string $color The colour of the text + * @return string + */ + public static function dumpResourceValue($resource, $html = true, $color = 'blue') + { + if (is_object($resource)) { + $resource = strval($resource); + } elseif (is_array($resource)) { + $resource = $resource['value']; + } + + $short = EasyRdf_Namespace::shorten($resource); + if ($html) { + $escaped = htmlentities($resource); + if (substr($resource, 0, 2) == '_:') { + $href = '#' . $escaped; + } else { + $href = $escaped; + } + if ($short) { + return "<a href='$href' style='text-decoration:none;color:$color'>$short</a>"; + } else { + return "<a href='$href' style='text-decoration:none;color:$color'>$escaped</a>"; + } + } else { + if ($short) { + return $short; + } else { + return $resource; + } + } + } + + /** Return pretty-print view of a literal + * + * This method is mainly intended for internal use and is used by + * EasyRdf_Graph and EasyRdf_Sparql_Result to format a literal + * for display. + * + * @param mixed $literal An EasyRdf_Literal object or an associative array + * @param bool $html Set to true to format the dump using HTML + * @param string $color The colour of the text + * @return string + */ + public static function dumpLiteralValue($literal, $html = true, $color = 'black') + { + if (is_object($literal)) { + $literal = $literal->toArray(); + } elseif (!is_array($literal)) { + $literal = array('value' => $literal); + } + + $text = '"'.$literal['value'].'"'; + if (isset($literal['lang'])) { + $text .= '@' . $literal['lang']; + } + if (isset($literal['datatype'])) { + $datatype = EasyRdf_Namespace::shorten($literal['datatype']); + $text .= "^^$datatype"; + } + + if ($html) { + return "<span style='color:$color'>". + htmlentities($text, ENT_COMPAT, "UTF-8"). + "</span>"; + } else { + return $text; + } + } + + /** Clean up and split a mime-type up into its parts + * + * @param string $mimeType A MIME Type, optionally with parameters + * @return array $type, $parameters + */ + public static function parseMimeType($mimeType) + { + $parts = explode(';', strtolower($mimeType)); + $type = trim(array_shift($parts)); + $params = array(); + foreach ($parts as $part) { + if (preg_match("/^\s*(\w+)\s*=\s*(.+?)\s*$/", $part, $matches)) { + $params[$matches[1]] = $matches[2]; + } + } + return array($type, $params); + } + + /** Execute a command as a pipe + * + * The proc_open() function is used to open a pipe to a + * a command line process, writing $input to STDIN, returning STDOUT + * and throwing an exception if anything is written to STDERR or the + * process returns non-zero. + * + * @param string $command The command to execute + * @param array $args Optional list of arguments to pass to the command + * @param string $input Optional buffer to send to the command + * @param string $dir Path to directory to run command in (defaults to /tmp) + * @return string The result of the command, printed to STDOUT + */ + public static function execCommandPipe($command, $args = null, $input = null, $dir = null) + { + $descriptorspec = array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ); + + // Use the system tmp directory by default + if (!$dir) { + $dir = sys_get_temp_dir(); + } + + if (is_array($args)) { + $fullCommand = implode( + ' ', + array_map('escapeshellcmd', array_merge(array($command), $args)) + ); + } else { + $fullCommand = escapeshellcmd($command); + if ($args) { + $fullCommand .= ' '.escapeshellcmd($args); + } + } + + $process = proc_open($fullCommand, $descriptorspec, $pipes, $dir); + if (is_resource($process)) { + // $pipes now looks like this: + // 0 => writeable handle connected to child stdin + // 1 => readable handle connected to child stdout + // 2 => readable handle connected to child stderr + + if ($input) { + fwrite($pipes[0], $input); + } + fclose($pipes[0]); + + $output = stream_get_contents($pipes[1]); + fclose($pipes[1]); + $error = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + // It is important that you close any pipes before calling + // proc_close in order to avoid a deadlock + $returnValue = proc_close($process); + if ($returnValue) { + throw new EasyRdf_Exception( + "Error while executing command $command: ".$error + ); + } + } else { + throw new EasyRdf_Exception( + "Failed to execute command $command" + ); + } + + return $output; + } +} -- GitLab