PageRenderTime 62ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/EasyRdf/Literal.php

http://github.com/njh/easyrdf
PHP | 306 lines | 137 code | 32 blank | 137 comment | 37 complexity | 3995fddb770accd0791119f072d55301 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. <?php
  2. /**
  3. * EasyRdf
  4. *
  5. * LICENSE
  6. *
  7. * Copyright (c) 2009-2011 Nicholas J Humfrey. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright notice,
  14. * this list of conditions and the following disclaimer in the documentation
  15. * and/or other materials provided with the distribution.
  16. * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
  17. * promote products derived from this software without specific prior
  18. * written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  23. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  24. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  25. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  26. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  27. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  29. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  30. * POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * @package EasyRdf
  33. * @copyright Copyright (c) 2009-2011 Nicholas J Humfrey
  34. * @license http://www.opensource.org/licenses/bsd-license.php
  35. * @version $Id$
  36. */
  37. /**
  38. * Class that represents an RDF Literal
  39. *
  40. * @package EasyRdf
  41. * @copyright Copyright (c) 2009-2011 Nicholas J Humfrey
  42. * @license http://www.opensource.org/licenses/bsd-license.php
  43. */
  44. class EasyRdf_Literal
  45. {
  46. /** @ignore a mapping from datatype uri to class name */
  47. private static $_datatypeMap = array();
  48. /** @ignore A mapping from class name to datatype URI */
  49. private static $_classMap = array();
  50. /** @ignore The value for this literal */
  51. protected $_value = null;
  52. /** @ignore The language of the literal (e.g. 'en') */
  53. protected $_lang = null;
  54. /** @ignore The datatype URI of the literal */
  55. protected $_datatype = null;
  56. /** Create a new literal object
  57. *
  58. * PHP values of type bool, int or float, will automatically be converted
  59. * to the corresponding datatype and PHP sub-class.
  60. *
  61. * If a registered datatype is given, then the registered subclass of EasyRdf_Literal
  62. * will instantiated.
  63. *
  64. * Note that literals are not required to have a language or datatype.
  65. * Literals cannot have both a language and a datatype.
  66. *
  67. * @param mixed $value The value of the literal or an associative array
  68. * @param string $lang The natural language of the literal or null (e.g. 'en')
  69. * @param string $datatype The datatype of the literal or null (e.g. 'xsd:integer')
  70. * @return object EasyRdf_Literal (or subclass of EasyRdf_Literal)
  71. */
  72. public static function create($value, $lang=null, $datatype=null)
  73. {
  74. if (EasyRdf_Utils::isAssociativeArray($value)) {
  75. if (isset($value['xml:lang'])) {
  76. $lang = $value['xml:lang'];
  77. } else if (isset($value['lang'])) {
  78. $lang = $value['lang'];
  79. }
  80. if (isset($value['datatype'])) {
  81. $datatype = $value['datatype'];
  82. }
  83. $value = isset($value['value']) ? $value['value'] : null;
  84. }
  85. if ($datatype == null) {
  86. if ($lang == null) {
  87. // Automatic datatype selection
  88. $datatype = self::getDatatypeForValue($value);
  89. }
  90. } else {
  91. // Expand shortened URIs (qnames)
  92. $datatype = EasyRdf_Namespace::expand($datatype);
  93. }
  94. // Work out what class to use for this datatype
  95. if (isset(self::$_datatypeMap[$datatype])) {
  96. $class = self::$_datatypeMap[$datatype];
  97. } else {
  98. $class = 'EasyRdf_Literal';
  99. }
  100. return new $class($value, $lang, $datatype);
  101. }
  102. /** Register an RDF datatype with a PHP class name
  103. *
  104. * When parsing registered class will be used whenever the datatype
  105. * is seen.
  106. *
  107. * When serialising a registered class, the mapping will be used to
  108. * set the datatype in the RDF.
  109. *
  110. * Example:
  111. * EasyRdf_Literal::registerDatatype('xsd:dateTime', 'My_DateTime_Class');
  112. *
  113. * @param string $datatype The RDF datatype (e.g. xsd:dateTime)
  114. * @param string $class The PHP class name (e.g. My_DateTime_Class)
  115. */
  116. public static function setDatatypeMapping($datatype, $class)
  117. {
  118. if (!is_string($datatype) or $datatype == null or $datatype == '') {
  119. throw new InvalidArgumentException(
  120. "\$datatype should be a string and cannot be null or empty"
  121. );
  122. }
  123. if (!is_string($class) or $class == null or $class == '') {
  124. throw new InvalidArgumentException(
  125. "\$class should be a string and cannot be null or empty"
  126. );
  127. }
  128. $datatype = EasyRdf_Namespace::expand($datatype);
  129. self::$_datatypeMap[$datatype] = $class;
  130. self::$_classMap[$class] = $datatype;
  131. }
  132. /** Remove the mapping between an RDF datatype and a PHP class name
  133. *
  134. * @param string $datatype The RDF datatype (e.g. xsd:dateTime)
  135. */
  136. public static function deleteDatatypeMapping($datatype)
  137. {
  138. if (!is_string($datatype) or $datatype == null or $datatype == '') {
  139. throw new InvalidArgumentException(
  140. "\$datatype should be a string and cannot be null or empty"
  141. );
  142. }
  143. $datatype = EasyRdf_Namespace::expand($datatype);
  144. if (isset(self::$_datatypeMap[$datatype])) {
  145. $class = self::$_datatypeMap[$datatype];
  146. unset(self::$_datatypeMap[$datatype]);
  147. unset(self::$_classMap[$class]);
  148. }
  149. }
  150. /** Get datatype URI for a PHP value.
  151. *
  152. * This static function is intended for internal use.
  153. * Given a PHP value, it will return an XSD datatype
  154. * URI for that value, for example:
  155. * http://www.w3.org/2001/XMLSchema#integer
  156. *
  157. * @return string A URI for the datatype of $value.
  158. */
  159. public static function getDatatypeForValue($value)
  160. {
  161. if (is_float($value)) {
  162. return 'http://www.w3.org/2001/XMLSchema#decimal';
  163. } else if (is_int($value)) {
  164. return 'http://www.w3.org/2001/XMLSchema#integer';
  165. } else if (is_bool($value)) {
  166. return 'http://www.w3.org/2001/XMLSchema#boolean';
  167. } else {
  168. return null;
  169. }
  170. }
  171. /** Constructor for creating a new literal
  172. *
  173. * @param string $value The value of the literal
  174. * @param string $lang The natural language of the literal or null (e.g. 'en')
  175. * @param string $datatype The datatype of the literal or null (e.g. 'xsd:string')
  176. * @return object EasyRdf_Literal
  177. */
  178. public function __construct($value, $lang=null, $datatype=null)
  179. {
  180. $this->_value = $value;
  181. $this->_lang = $lang ? $lang : null;
  182. $this->_datatype = $datatype ? $datatype : null;
  183. if ($this->_datatype) {
  184. // Expand shortened URIs (qnames)
  185. $this->_datatype = EasyRdf_Namespace::expand($this->_datatype);
  186. // Literals can not have both a language and a datatype
  187. $this->_lang = null;
  188. } else {
  189. // Set the datatype based on the subclass
  190. $class = get_class($this);
  191. if (isset(self::$_classMap[$class])) {
  192. $this->_datatype = self::$_classMap[$class];
  193. $this->_lang = null;
  194. }
  195. }
  196. // Cast to string if it is a string
  197. if ($this->_lang or !$this->_datatype or $this->_datatype == 'http://www.w3.org/2001/XMLSchema#string') {
  198. settype($this->_value, 'string');
  199. }
  200. }
  201. /** Returns the value of the literal.
  202. *
  203. * @return string Value of this literal.
  204. */
  205. public function getValue()
  206. {
  207. return $this->_value;
  208. }
  209. /** Returns the full datatype URI of the literal.
  210. *
  211. * @return string Datatype URI of this literal.
  212. */
  213. public function getDatatypeUri()
  214. {
  215. return $this->_datatype;
  216. }
  217. /** Returns the shortened datatype URI of the literal.
  218. *
  219. * @return string Datatype of this literal (e.g. xsd:integer).
  220. */
  221. public function getDatatype()
  222. {
  223. if ($this->_datatype) {
  224. return EasyRdf_Namespace::shorten($this->_datatype);
  225. } else {
  226. return null;
  227. }
  228. }
  229. /** Returns the language of the literal.
  230. *
  231. * @return string Language of this literal.
  232. */
  233. public function getLang()
  234. {
  235. return $this->_lang;
  236. }
  237. /** Returns the properties of the literal as an associative array
  238. *
  239. * For example:
  240. * array('type' => 'literal', 'value' => 'string value')
  241. *
  242. * @return array The properties of the literal
  243. */
  244. public function toArray()
  245. {
  246. $array = array(
  247. 'type' => 'literal',
  248. 'value' => strval($this)
  249. );
  250. if ($this->_datatype)
  251. $array['datatype'] = $this->_datatype;
  252. if ($this->_lang)
  253. $array['lang'] = $this->_lang;
  254. return $array;
  255. }
  256. /** Magic method to return the value of a literal when casted to string
  257. *
  258. * @return string The value of the literal
  259. */
  260. public function __toString()
  261. {
  262. return isset($this->_value) ? strval($this->_value) : '';
  263. }
  264. /** Return pretty-print view of the literal
  265. *
  266. * @param bool $html Set to true to format the dump using HTML
  267. * @param string $color The colour of the text
  268. * @return string
  269. */
  270. public function dumpValue($html=true, $color='black')
  271. {
  272. return EasyRdf_Utils::dumpLiteralValue($this, $html, $color);
  273. }
  274. }