Source for file Model.php

Documentation is available at Model.php

  1. <?php
  2.  
  3. // ----------------------------------------------------------------------------------
  4. // Class: Model
  5. // ----------------------------------------------------------------------------------
  6.  
  7. /**
  8. * Abstract superclass of MemModel and DbModel. A model is a programming interface to an RDF graph.
  9. * An RDF graph is a directed labeled graph, as described in http://www.w3.org/TR/rdf-mt/.
  10. * It can be defined as a set of <S, P, O> triples, where P is a uriref, S is either
  11. * a uriref or a blank node, and O is either a uriref, a blank node, or a literal.
  12. *
  13. * <BR><BR>History:<UL>
  14. * <LI>01-05-2006 : Function sparqlQuery() added (tobias.gauss@web.de)</LI>
  15. * <LI>03-29-2005 : Function visualizeGraph() added (anton1@koestlbacher.de)</LI>
  16. * <LI>12-06-2004 : Functions findForward() and getMemModelByRDQL() added. (anton1@koestlbacher.de) </LI>
  17. * <LI>10-30-2004 : GRDDL-Support (see http://www.w3.org/TR/grddl/) added. (tobias.gauss@web.de) </LI>
  18. * <LI>09-22-2004 : Function getUniqueResourceURI(): default bNode prefix is used,
  19. * if no other is defined. Returns unique URIs, without checking the model first.
  20. * <LI>09-07-2004 : Function load improved. (auer@informatik.uni-leipzig.de)</LI>
  21. * <LI>03-26-2004 : _addStatementFromAnotherModel() added
  22. * : saveAs() moved to the child classes</LI>
  23. * <LI>11-13-2003 : Function saveAs added
  24. * <LI>07-27-2003 : This is an abstract parent class for MemModel and DbModel.
  25. * The previous class Model has been renamed to MemModel
  26. *
  27. *
  28. *
  29. * @version V0.9.3
  30. * @author Radoslaw Oldakowski <radol@gmx.de>
  31. * @author Daniel Westphal <mail@d-westphal.de>
  32. *
  33. * @package model
  34. * @access public
  35. */
  36.  
  37. Class Model extends Object {
  38.  
  39.  
  40. /**
  41. * Base URI of the Model.
  42. * Affects creating of new resources and serialization syntax.
  43. *
  44. * @var string
  45. * @access private
  46. */
  47. var $baseURI;
  48.  
  49. /**
  50. * Number of the last assigned bNode.
  51. *
  52. *
  53. * @var integer
  54. * @access private
  55. */
  56. var $bNodeCount;
  57.  
  58.  
  59.  
  60. /**
  61. * Notice for people who are used to work with older versions of RAP.
  62. *
  63. * @throws PHPError
  64. * @access public
  65. */
  66. function Model() {
  67.  
  68. $errmsg = ''Since RAP 0.6 the class for manipulating memory models has been renamed to MemModel.'';
  69. $errmsg .= ''<br>Sorry for this inconvenience.<br>'';
  70.  
  71. trigger_error($errmsg, E_USER_ERROR);
  72. }
  73.  
  74.  
  75. /**
  76. * Return current baseURI.
  77. *
  78. * @return string
  79. * @access public
  80. */
  81. function getBaseURI() {
  82.  
  83. return $this->baseURI;
  84. }
  85.  
  86.  
  87. /**
  88. * Load a model from a file containing RDF, N3, N-Triples or a xhtml document containing RDF.
  89. * This function recognizes the suffix of the filename (.n3 or .rdf) and
  90. * calls a suitable parser, if no $type is given as string ("rdf" "n3" "nt");
  91. * If the model is not empty, the contents of the file is added to this DbModel.
  92. *
  93. * @param string $filename
  94. * @param string $type
  95. * @param boolean $stream
  96. * @access public
  97. */
  98. function load($filename, $type = NULL, $stream=false) {
  99.  
  100. if ((isset($type)) && ($type ==''n3'') OR ($type ==''nt'')) {
  101. // Import Package Syntax
  102. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  103. $parser = new N3Parser();
  104. }elseif ((isset($type)) && ($type ==''rdf'')) {
  105. // Import Package Syntax
  106. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  107. $parser = new RdfParser();
  108. }elseif ((isset($type)) && ($type ==''grddl'')) {
  109. // Import Package Syntax
  110. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_GRDDL);
  111. $parser = new GRDDLParser();
  112. }else {
  113. // create a parser according to the suffix of the filename
  114. // if there is no suffix assume the file to be XML/RDF
  115. preg_match("/\.([a-zA-Z0-9_]+)$/", $filename, $suffix);
  116. if (isset($suffix[1]) && (strtolower($suffix[1]) == ''n3'' OR strtolower($suffix[1]) == ''nt'')){
  117. // Import Package Syntax
  118. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  119. $parser = new N3Parser();
  120. }elseif (isset($suffix[1]) && (strtolower($suffix[1]) == ''htm'' OR strtolower($suffix[1]) == ''html'' OR strtolower($suffix[1]) == ''xhtml'')){
  121. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_GRDDL);
  122. $parser = new GRDDLParser();
  123. }else{
  124. // Import Package Syntax
  125. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  126. $parser = new RdfParser();}
  127. };
  128.  
  129. if(($stream && $type==''rdf'')||($stream && $type==''n3''))
  130. $temp=&$parser->generateModel($filename,false,$this);
  131. else{
  132. $temp=&$parser->generateModel($filename);
  133. }
  134. $this->addModel($temp);
  135. if($this->getBaseURI()== null)
  136. $this->setBaseURI($temp->getBaseURI());
  137.  
  138. }
  139.  
  140.  
  141. /**
  142. * Adds a statement from another model to this model.
  143. * If the statement to be added contains a blankNode with an identifier
  144. * already existing in this model, a new blankNode is generated.
  145. *
  146. * @param Object Statement $statement
  147. * @access private
  148. */
  149. function _addStatementFromAnotherModel($statement, &$blankNodes_tmp) {
  150.  
  151. $subject = $statement->getSubject();
  152. $object = $statement->getObject();
  153.  
  154. if (is_a($subject, "BlankNode")) {
  155. $label = $subject->getLabel();
  156. if (!array_key_exists($label, $blankNodes_tmp))
  157. {
  158. if ($this->findFirstMatchingStatement($subject, NULL, NULL)
  159. || $this->findFirstMatchingStatement(NULL, NULL, $subject))
  160. {
  161. $blankNodes_tmp[$label] = new BlankNode($this);
  162. $statement->subj = $blankNodes_tmp[$label];
  163. } else {
  164. $blankNodes_tmp[$label] = $subject;
  165. }
  166. } else
  167. $statement->subj = $blankNodes_tmp[$label];
  168. }
  169.  
  170. if (is_a($object, "BlankNode")) {
  171. $label = $object->getLabel();
  172. if (!array_key_exists($label, $blankNodes_tmp))
  173. {
  174. if ($this->findFirstMatchingStatement($object, NULL, NULL)
  175. || $this->findFirstMatchingStatement(NULL, NULL, $object))
  176. {
  177. $blankNodes_tmp[$label] = new BlankNode($this);
  178. $statement->obj = $blankNodes_tmp[$label];
  179. } else {
  180. $blankNodes_tmp[$label] = $object;
  181. }
  182. } else
  183. $statement->obj = $blankNodes_tmp[$label];
  184. }
  185. $this->add($statement);
  186. }
  187.  
  188.  
  189.  
  190. /**
  191. * Internal method, that returns a resource URI that is unique for the Model.
  192. * URIs are generated using the base_uri of the DbModel, the prefix and a unique number.
  193. * If no prefix is defined, the bNode prefix, defined in constants.php, is used.
  194. *
  195. * @param string $prefix
  196. * @return string
  197. * @access private
  198. */
  199. function getUniqueResourceURI($prefix = false)
  200. {
  201. static $bNodeCount;
  202. if(!$bNodeCount)
  203. $bNodeCount = 0;
  204.  
  205. if(!$prefix)
  206. $prefix=BNODE_PREFIX;
  207.  
  208. return $prefix.++$bNodeCount;
  209. }
  210.  
  211. /**
  212. * Returns a ResModel with this model as baseModel.
  213. *
  214. * @param constant $modelType
  215. * @param string $baseURI
  216. * @return object MemModel
  217. * @access public
  218. */
  219. function & getResmodel()
  220. {
  221. require_once( RDFAPI_INCLUDE_DIR . PACKAGE_RESMODEL);
  222. return new ResModel($this);
  223. }
  224.  
  225. /**
  226. * Returns an OntModel with this model as baseModel.
  227. * $vocabulary has to be one of the following constants (currently only one is supported):
  228. * RDFS_VOCABULARY to select a RDFS Vocabulary.
  229. * You can supply a base URI
  230. *
  231. * @param constant $vocabulary
  232. * @return object OntModel
  233. * @access public
  234. */
  235. function & getOntModel($vocabulary)
  236. {
  237. require_once( RDFAPI_INCLUDE_DIR . PACKAGE_ONTMODEL);
  238. return new OntModel(& $this, $vocab);
  239. }
  240.  
  241.  
  242.  
  243. /**
  244. * Searches for triples using find() and tracks forward blank nodes
  245. * until the final objects in the retrieved subgraphs are all named resources.
  246. * The method calls itself recursivly until the result is complete.
  247. * NULL input for subject, predicate or object will match anything.
  248. * Inputparameters are ignored for recursivly found statements.
  249. * Returns a new MemModel or adds (without checking for duplicates)
  250. * the found statements to a given MemModel.
  251. * Returns an empty MemModel, if nothing is found.
  252. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  253. * WARNING: This method can be slow with large models.
  254. * NOTE: Blank nodes are not renamed, they keep the same nodeIDs
  255. * as in the queried model!
  256. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  257. *
  258. * @author Anton Köstlbacher <anton1@koestlbacher.de>
  259. * @param object Node $subject
  260. * @param object Node $predicate
  261. * @param object Node $object
  262. * @param object MemModel $object
  263. * @return object MemModel
  264. * @access public
  265. * @throws PhpError
  266. */
  267.  
  268. function findForward($subject, $predicate, $object, $newModel = NULL)
  269. {
  270. if (!is_a($newModel, "MemModel"))
  271. {
  272. $newModel = New MemModel;
  273. }
  274.  
  275. if (is_a($this, "DbModel"))
  276. {
  277. $model = $this;
  278. $res = $model->find($subject, $predicate, $object);
  279. $it = $res->getStatementIterator();
  280. }
  281. elseif (is_a($this, "MemModel")) {
  282. $model = $this;
  283. $it = $model->findAsIterator($subject, $predicate, $object);
  284. }
  285. elseif (is_a($this, "ResModel")) {
  286. $model = $this->model;
  287. $it = $model->findAsIterator($subject, $predicate, $object);
  288. }
  289.  
  290. while ($it->hasNext())
  291. {
  292. $statement = $it->next();
  293. $newModel->add($statement);
  294. if (is_a($statement->object(),''BlankNode''))
  295. {
  296. $model->findForward($statement->object(), NULL, NULL,&$newModel);
  297. }
  298. }
  299. return $newModel;
  300. }
  301.  
  302.  
  303. /**
  304. * Perform an RDQL query on this Model. Should work with all types of models.
  305. * This method returns a MemModel containing the result statements.
  306. * If $closure is set to TRUE, the result will additionally contain
  307. * statements found by the findForward-method for blank nodes.
  308. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  309. * WARNING: If called with $closure = TRUE this method
  310. * can be slow with large models.
  311. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  312. *
  313. * @author Anton Köstlbacher <anton1@koestlbacher.de>
  314. * @author code snippets taken from the RAP Netapi by Phil Dawes and Chris Bizer
  315. * @access public
  316. * @param string $queryString
  317. * @param boolean $closure
  318. * @return object MemModel
  319. *
  320. */
  321.  
  322. function & getMemModelByRDQL($queryString, $closure = FALSE)
  323. {
  324. require_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  325. $parser = new RdqlParser();
  326. $parsedQuery =& $parser->parseQuery($queryString);
  327.  
  328. // If there are variables used in the pattern but not
  329. // in the select clause, add them to the select clause
  330. foreach ($parsedQuery[''patterns''] as $n => $pattern)
  331. {
  332. foreach ($pattern as $key => $val_1)
  333. {
  334. if ($val_1[''value'']{0}==''?'')
  335. {
  336. if (!in_array($val_1[''value''],$parsedQuery[''selectVars'']))
  337. {
  338. array_push($parsedQuery[''selectVars''],$val_1[''value'']);
  339. }
  340. }
  341. }
  342. }
  343.  
  344. if (is_a($this, "DbModel"))
  345. {
  346. $engine = new RdqlDbEngine();
  347. $model = $this;
  348. }
  349. elseif (is_a($this, "MemModel"))
  350. {
  351. $engine = new RdqlMemEngine();
  352. $model = $this;
  353. }
  354. elseif (is_a($this, "ResModel"))
  355. {
  356. $engine = new RdqlMemEngine();
  357. $model = $this->model;
  358. }
  359.  
  360. $res = $engine->queryModel($model,$parsedQuery,TRUE);
  361. $rdqlIter = new RdqlResultIterator($res);
  362. $newModel = new MemModel();
  363.  
  364. // Build statements from RdqlResultIterator
  365. while ($rdqlIter->hasNext()) {
  366. $result = $rdqlIter->next();
  367. foreach ($parsedQuery[''patterns''] as $n => $pattern)
  368. {
  369. if (substr($pattern[''subject''][''value''], 0, 1) == ''?'')
  370. {
  371. $subj = $result[$pattern[''subject''][''value'']];
  372. }
  373. else
  374. {
  375. $subj = new Resource($pattern[''subject''][''value'']);
  376. }
  377. if (substr($pattern[''predicate''][''value''], 0, 1) == ''?'')
  378. {
  379. $pred = $result[$pattern[''predicate''][''value'']];
  380. }
  381. else
  382. {
  383. $pred = new Resource($pattern[''predicate''][''value'']);
  384. }
  385.  
  386. if (substr($pattern[''object''][''value''], 0, 1) == ''?'')
  387. {
  388. $obj = $result[$pattern[''object''][''value'']];
  389. }
  390. else
  391. {
  392. if (isset($pattern[''object''][''is_literal'']))
  393. {
  394. $obj = new Literal($pattern[''object''][''value'']);
  395. $obj->setDatatype($pattern[''object''][''l_dtype'']);
  396. $obj->setLanguage($pattern[''object''][''l_lang'']);
  397. }
  398. else
  399. {
  400. $obj = new Resource($pattern[''object''][''value'']);
  401. }
  402. }
  403.  
  404. $statement = new Statement($subj,$pred,$obj);
  405. $newModel->add($statement);
  406.  
  407. // findForward() Statements containing an eventually given blank node
  408. // and add them to the result, if closure = true
  409. if (is_a($statement->object(),''BlankNode'') && $closure == True)
  410. {
  411. $newModel = $model->findForward($statement->object(),NULL,NULL,&$newModel);
  412. }
  413. if (is_a($statement->subject(),''BlankNode'') && $closure == True)
  414. {
  415. $newModel = $model->findForward($statement->subject(),NULL,NULL,&$newModel);
  416. }
  417. }
  418. }
  419. return $newModel;
  420. }
  421.  
  422. /**
  423. * Alias for RDFUtil::visualiseGraph(&$model, $format, $short_prefix)
  424. *
  425. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  426. * Note: See RDFUtil for further Information.
  427. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  428. *
  429. * @author Anton Köstlbacher <anton1@koestlbacher.de>
  430. * @param string $format
  431. * @param boolean $short_prefix
  432. * @return string, binary
  433. * @access public
  434. * @throws PhpError
  435. */
  436.  
  437. function visualize($format = "dot", $short_prefix = TRUE)
  438. {
  439. return RDFUtil::visualizeGraph($this, $format, $short_prefix);
  440. }
  441. /**
  442. * Performs a SPARQL query against a model. The model is converted to
  443. * an RDF Dataset. The result can be retrived in SPARQL Query Results XML Format or
  444. * as an array containing the variables an their bindings.
  445. *
  446. * @param String $query the sparql query string
  447. * @param String $resultform the result form (''xml'' for SPARQL Query Results XML Format)
  448. * @return String/array
  449. */
  450. function sparqlQuery($query,$resultform = false){
  451. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SPARQL);
  452. include_once(RDFAPI_INCLUDE_DIR.PACKAGE_DATASET);
  453. $dataset = new DatasetMem();
  454. $dataset->setDefaultGraph($this);
  455. $parser = new SparqlParser();
  456. $q = $parser->parse($query);
  457. $eng = new SparqlEngine();
  458. return $eng->queryModel($dataset,$q,$resultform);
  459. }
  460. } // end: Model
  461.  
  462. ?>

Documentation generated on Fri, 13 Jan 2006 07:48:36 +0100 by phpDocumentor 1.3.0RC4