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.  *
  14.  * @version  $Id: fsource_model__modelModel.php.html 443 2007-06-01 16:25:38Z cax $
  15.  * @author Radoslaw Oldakowski <radol@gmx.de>
  16.  * @author Daniel Westphal <mail@d-westphal.de>
  17.  *
  18.  * @package model
  19.  * @access    public
  20.  */
  21. class Model extends Object
  22. {
  23.     /**
  24.     * Base URI of the Model.
  25.     * Affects creating of new resources and serialization syntax.
  26.     *
  27.     * @var     string 
  28.     * @access    private
  29.     */
  30.     var $baseURI;
  31.  
  32.     /**
  33.     * Number of the last assigned bNode.
  34.     *
  35.     * @var     integer 
  36.     * @access    private
  37.     */
  38.     var $bNodeCount;
  39.  
  40.     /**
  41.     *   SparqlParser so we can re-use it
  42.     *   @var Parser 
  43.     */
  44.     var $queryParser = null;
  45.  
  46.  
  47.  
  48.     /**
  49.     * Notice for people who are used to work with older versions of RAP.
  50.     *
  51.     * @throws  PHPError
  52.     * @access    public
  53.     */
  54.     function Model()
  55.     {
  56.  
  57.         $errmsg  'Since RAP 0.6 the class for manipulating memory models has been renamed to MemModel.';
  58.         $errmsg .= '<br>Sorry for this inconvenience.<br>';
  59.  
  60.         trigger_error($errmsgE_USER_ERROR);
  61.     }
  62.  
  63.  
  64.  
  65.     /**
  66.     * Return current baseURI.
  67.     *
  68.     * @return  string 
  69.     * @access    public
  70.     */
  71.     function getBaseURI()
  72.     {
  73.         return $this->baseURI;
  74.     }
  75.  
  76.  
  77.  
  78.     /**
  79.     * Load a model from a file containing RDF, N3, N-Triples or a xhtml document containing RDF.
  80.     * This function recognizes the suffix of the filename (.n3 or .rdf) and
  81.     * calls a suitable parser, if no $type is given as string ("rdf" "n3" "nt");
  82.     * If the model is not empty, the contents of the file is added to this DbModel.
  83.     *
  84.     * @param     string     $filename 
  85.     * @param     string     $type 
  86.     * @param   boolean $stream 
  87.     * @access    public
  88.     */
  89.     function load($filename$type NULL$stream=false)
  90.     {
  91.         if ((isset($type)) && ($type =='n3'OR ($type =='nt')) {
  92.             // Import Package Syntax
  93.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  94.             $parser new N3Parser();
  95.         }elseif ((isset($type)) && ($type =='rdf')) {
  96.             // Import Package Syntax
  97.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  98.             $parser new RdfParser();
  99.         }elseif ((isset($type)) && ($type =='grddl')) {
  100.             // Import Package Syntax
  101.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_GRDDL);
  102.             $parser new GRDDLParser();
  103.         }elseif ((isset($type)) && ($type =='rss')) {
  104.             // Import Package Syntax
  105.             include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RSS);
  106.             $parser new RssParser();
  107.         }else {
  108.             // create a parser according to the suffix of the filename
  109.             // if there is no suffix assume the file to be XML/RDF
  110.             preg_match("/\.([a-zA-Z0-9_]+)$/"$filename$suffix);
  111.             if (isset($suffix[1]&& (strtolower($suffix[1]== 'n3' OR strtolower($suffix[1]== 'nt')){
  112.                 // Import Package Syntax
  113.                 include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_N3);
  114.                 $parser new N3Parser();
  115.             }elseif (isset($suffix[1]&& (strtolower($suffix[1]== 'htm' OR strtolower($suffix[1]== 'html' OR strtolower($suffix[1]== 'xhtml')){
  116.                     include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_GRDDL);
  117.                     $parser new GRDDLParser();
  118.             }else{
  119.                 // Import Package Syntax
  120.                 include_once(RDFAPI_INCLUDE_DIR.PACKAGE_SYNTAX_RDF);
  121.                 $parser new RdfParser();
  122.             }
  123.         };
  124.  
  125.         if (($stream && $type=='rdf')||($stream && $type=='n3')) {
  126.                 $temp=&$parser->generateModel($filename,false,$this);
  127.         else{
  128.                 $temp=&$parser->generateModel($filename);
  129.         }
  130.         $this->addModel($temp);
  131.         if($this->getBaseURI()== null)
  132.             $this->setBaseURI($temp->getBaseURI());
  133.     }
  134.  
  135.  
  136.  
  137.     /**
  138.     * Adds a statement from another model to this model.
  139.     * If the statement to be added contains a blankNode with an identifier
  140.     * already existing in this model, a new blankNode is generated.
  141.     *
  142.     * @param     Object Statement   $statement
  143.     * @access    private
  144.     */
  145.     function _addStatementFromAnotherModel($statement&$blankNodes_tmp)
  146.     {
  147.         $subject $statement->getSubject();
  148.         $object $statement->getObject();
  149.  
  150.         if (is_a($subject"BlankNode")) {
  151.             $label $subject->getLabel();
  152.             if (!array_key_exists($label$blankNodes_tmp))
  153.             {
  154.                 if ($this->findFirstMatchingStatement($subjectNULLNULL)
  155.                 || $this->findFirstMatchingStatement(NULLNULL$subject))
  156.                 {
  157.                 $blankNodes_tmp[$labelnew BlankNode($this);
  158.                 $statement->subj $blankNodes_tmp[$label];
  159.                 else {
  160.                 $blankNodes_tmp[$label$subject;
  161.                 }
  162.             else
  163.                 $statement->subj $blankNodes_tmp[$label];
  164.         }
  165.  
  166.         if (is_a($object"BlankNode")) {
  167.             $label $object->getLabel();
  168.             if (!array_key_exists($label$blankNodes_tmp))
  169.             {
  170.                 if ($this->findFirstMatchingStatement($objectNULLNULL)
  171.                 || $this->findFirstMatchingStatement(NULLNULL$object))
  172.                 {
  173.                 $blankNodes_tmp[$labelnew BlankNode($this);
  174.                 $statement->obj $blankNodes_tmp[$label];
  175.                 else {
  176.                 $blankNodes_tmp[$label$object;
  177.                 }
  178.             else
  179.                 $statement->obj $blankNodes_tmp[$label];
  180.         }
  181.         $this->add($statement);
  182.     }
  183.  
  184.  
  185.  
  186.     /**
  187.     * Internal method, that returns a resource URI that is unique for the Model.
  188.     * URIs are generated using the base_uri of the DbModel, the prefix and a unique number.
  189.     * If no prefix is defined, the bNode prefix, defined in constants.php, is used.
  190.     *
  191.     * @param    string    $prefix 
  192.     * @return    string 
  193.     * @access    private
  194.     */
  195.     function getUniqueResourceURI($prefix false)
  196.     {
  197.         static $bNodeCount;
  198.         if(!$bNodeCount)
  199.             $bNodeCount 0;
  200.  
  201.         if(!$prefix)
  202.             $prefix=BNODE_PREFIX;
  203.  
  204.         return $prefix.++$bNodeCount;
  205.     }
  206.  
  207.  
  208.  
  209.     /**
  210.     * Returns a ResModel with this model as baseModel. This is the same as
  211.     * ModelFactory::getResModelForBaseModel($this).
  212.     *
  213.     * @return    object    ResModel 
  214.     * @access    public
  215.     */
  216.     function getResModel()
  217.     {
  218.         return ModelFactory::getResModelForBaseModel($this);
  219.     }
  220.  
  221.  
  222.  
  223.     /**
  224.     * Returns an OntModel with this model as baseModel.
  225.     * $vocabulary has to be one of the following constants (currently only one is supported):
  226.     * RDFS_VOCABULARY to select a RDFS Vocabulary.
  227.     *
  228.     * This is the same as ModelFactory::getOntModelForBaseModel($this, $vocabulary).
  229.     *
  230.     * @param   constant  $vocabulary 
  231.     * @return    object    OntModel 
  232.     * @access    public
  233.     */
  234.     function getOntModel($vocabulary)
  235.     {
  236.         return ModelFactory::getOntModelForBaseModel($this$vocabulary);
  237.     }
  238.  
  239.  
  240.  
  241.     /**
  242.     * Searches for triples using find() and tracks forward blank nodes
  243.     * until the final objects in the retrieved subgraphs are all named resources.
  244.     * The method calls itself recursivly until the result is complete.
  245.     * NULL input for subject, predicate or object will match anything.
  246.     * Inputparameters are ignored for recursivly found statements.
  247.     * Returns a new MemModel or adds (without checking for duplicates)
  248.     * the found statements to a given MemModel.
  249.     * Returns an empty MemModel, if nothing is found.
  250.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  251.     * WARNING: This method can be slow with large models.
  252.     * NOTE:    Blank nodes are not renamed, they keep the same nodeIDs
  253.     *          as in the queried model!
  254.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  255.     *
  256.     * @author   Anton Koestlbacher <anton1@koestlbacher.de>
  257.     * @param    object Node     $subject 
  258.     * @param    object Node     $predicate 
  259.     * @param    object Node     $object 
  260.     * @param    object MemModel $object 
  261.     * @return   object MemModel 
  262.     * @access   public
  263.     * @throws   PhpError
  264.     */
  265.     function findForward($subject$predicate$object&$newModel NULL)
  266.     {
  267.         if (!is_a($newModel"MemModel"))
  268.         {
  269.             $newModel New MemModel;
  270.         }
  271.  
  272.         if (is_a($this"DbModel"))
  273.         {
  274.             $model $this;
  275.             $res   $model->find($subject$predicate$object);
  276.             $it    $res->getStatementIterator();
  277.         }
  278.         elseif (is_a($this"MemModel")) {
  279.             $model $this;
  280.             $it    $model->findAsIterator($subject$predicate$object);
  281.         }
  282.         elseif (is_a($this"ResModel")) {
  283.             $model $this->model;
  284.             $it    $model->findAsIterator($subject$predicate$object);
  285.         }
  286.  
  287.         while ($it->hasNext())
  288.         {
  289.             $statement $it->next();
  290.             $newModel->add($statement);
  291.             if (is_a($statement->object(),'BlankNode'))
  292.             {
  293.                 $model->findForward($statement->object()NULLNULL$newModel);
  294.             }
  295.         }
  296.         return $newModel;
  297.     }
  298.  
  299.  
  300.  
  301.     /**
  302.     * Perform an RDQL query on this Model. Should work with all types of models.
  303.     * This method returns a MemModel containing the result statements.
  304.     * If $closure is set to TRUE, the result will additionally contain
  305.     * statements found by the findForward-method for blank nodes.
  306.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  307.     * WARNING: If called with $closure = TRUE this method
  308.     *          can be slow with large models.
  309.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  310.     *
  311.     * @author   Anton K�tlbacher <anton1@koestlbacher.de>
  312.     * @author   code snippets taken from the RAP Netapi by Phil Dawes and Chris Bizer
  313.     * @access   public
  314.     * @param    string $queryString 
  315.     * @param    boolean $closure 
  316.     * @return   object MemModel 
  317.     *
  318.     */
  319.     function getMemModelByRDQL($queryString$closure FALSE)
  320.     {
  321.         require_once(RDFAPI_INCLUDE_DIR.PACKAGE_RDQL);
  322.         $parser new RdqlParser();
  323.         $parsedQuery =$parser->parseQuery($queryString);
  324.  
  325.         // If there are variables used in the pattern but not
  326.         // in the select clause, add them to the select clause
  327.         foreach ($parsedQuery['patterns'as $n => $pattern)
  328.         {
  329.             foreach ($pattern as $key => $val_1)
  330.             {
  331.                 if ($val_1['value']{0}=='?')
  332.                 {
  333.                     if (!in_array($val_1['value'],$parsedQuery['selectVars']))
  334.                     {
  335.                     array_push($parsedQuery['selectVars'],$val_1['value']);
  336.                     }
  337.                 }
  338.             }
  339.         }
  340.  
  341.         if (is_a($this"DbModel"))
  342.         {
  343.             $engine new RdqlDbEngine();
  344.             $model  $this;
  345.         }
  346.         elseif (is_a($this"MemModel"))
  347.         {
  348.             $engine new RdqlMemEngine();
  349.             $model  $this;
  350.         }
  351.         elseif (is_a($this"ResModel"))
  352.         {
  353.             $engine new RdqlMemEngine();
  354.             $model  $this->model;
  355.         }
  356.  
  357.         $res $engine->queryModel($model,$parsedQuery,TRUE);
  358.         $rdqlIter new RdqlResultIterator($res);
  359.         $newModel new MemModel();
  360.  
  361.         // Build statements from RdqlResultIterator
  362.         while ($rdqlIter->hasNext()) {
  363.             $result $rdqlIter->next();
  364.             foreach ($parsedQuery['patterns'as $n => $pattern)
  365.             {
  366.                 if (substr($pattern['subject']['value']01== '?')
  367.                 {
  368.                     $subj $result[$pattern['subject']['value']];
  369.                 }
  370.                 else
  371.                 {
  372.                     $subj new Resource($pattern['subject']['value']);
  373.                 }
  374.                 if (substr($pattern['predicate']['value']01== '?')
  375.                 {
  376.                     $pred $result[$pattern['predicate']['value']];
  377.                 }
  378.                 else
  379.                 {
  380.                     $pred new Resource($pattern['predicate']['value']);
  381.                 }
  382.  
  383.                 if (substr($pattern['object']['value']01== '?')
  384.                 {
  385.                     $obj $result[$pattern['object']['value']];
  386.                 }
  387.                 else
  388.                 {
  389.                     if (isset($pattern['object']['is_literal']))
  390.                     {
  391.                         $obj new Literal($pattern['object']['value']);
  392.                         $obj->setDatatype($pattern['object']['l_dtype']);
  393.                         $obj->setLanguage($pattern['object']['l_lang']);
  394.                     }
  395.                     else
  396.                     {
  397.                         $obj new Resource($pattern['object']['value']);
  398.                     }
  399.                 }
  400.  
  401.                 $statement new Statement($subj,$pred,$obj);
  402.                 $newModel->add($statement);
  403.  
  404.                 // findForward() Statements containing an eventually given blank node
  405.                 // and add them to the result, if closure = true
  406.                 if (is_a($statement->object(),'BlankNode'&& $closure == True)
  407.                 {
  408.                     $newModel $model->findForward($statement->object(),NULL,NULL$newModel);
  409.                 }
  410.                 if (is_a($statement->subject(),'BlankNode'&& $closure == True)
  411.                 {
  412.                     $newModel $model->findForward($statement->subject(),NULL,NULL$newModel);
  413.                 }
  414.             }
  415.         }
  416.         return $newModel;
  417.     }
  418.  
  419.  
  420.  
  421.     /**
  422.     * Alias for RDFUtil::visualiseGraph(&$model, $format, $short_prefix)
  423.     *
  424.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  425.     * Note: See RDFUtil for further Information.
  426.     * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  427.     *
  428.     * @author   Anton K�tlbacher <anton1@koestlbacher.de>
  429.     * @param    string  $format 
  430.     * @param    boolean $short_prefix 
  431.     * @return   string, binary
  432.     * @access   public
  433.     * @throws   PhpError
  434.     */
  435.     function visualize($format "dot"$short_prefix TRUE)
  436.     {
  437.         return RDFUtil::visualizeGraph($this$format$short_prefix);
  438.     }
  439.  
  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.     {
  452.         list($engine$dataset$this->_prepareSparql();
  453.         return $engine->queryModel(
  454.             $dataset,
  455.             $this->_parseSparqlQuery($query),
  456.             $resultform
  457.         );
  458.     }//function sparqlQuery($query,$resultform = false)
  459.  
  460.  
  461.  
  462.     /**
  463.     *   Prepares a sparql query and returns a prepared statement
  464.     *   that can be executed with data later on.
  465.     *
  466.     *   @param string $query Sparql query to prepare.
  467.     *   @return SparqlEngine_PreparedStatement  prepared statement object
  468.     */
  469.     function sparqlPrepare($query)
  470.     {
  471.         list($engine$dataset$this->_prepareSparql();
  472.         return $engine->prepare(
  473.             $dataset,
  474.             $this->_parseSparqlQuery($query)
  475.          );
  476.     }//function sparqlPrepare($query)
  477.  
  478.  
  479.  
  480.     /**
  481.     *   Prepares everything for SparqlEngine-usage
  482.     *   Loads the files, creates instances for SparqlEngine and
  483.     *   Dataset...
  484.     *
  485.     *   @return array First value is the sparql engine, second the dataset
  486.     */
  487.     function _prepareSparql()
  488.     {
  489.         require_once RDFAPI_INCLUDE_DIR 'sparql/SparqlEngine.php';
  490.         require_once RDFAPI_INCLUDE_DIR 'dataset/DatasetMem.php';
  491.  
  492.         $dataset new DatasetMem();
  493.         $dataset->setDefaultGraph($this);
  494.  
  495.         return array(
  496.             SparqlEngine::factory($this),
  497.             $dataset
  498.         );
  499.     }//function _prepareSparql()
  500.  
  501.  
  502.  
  503.     /**
  504.     *   Parses an query and returns the parsed form.
  505.     *   If the query is not a string but a Query object,
  506.     *   it will just be returned.
  507.     *
  508.     *   @param $query mixed String or Query object
  509.     *   @return Query query object
  510.     *   @throws Exception If $query is no string and no Query object
  511.     */
  512.     function _parseSparqlQuery($query)
  513.     {
  514.         if ($this->queryParser === null{
  515.             require_once RDFAPI_INCLUDE_DIR 'sparql/SparqlParser.php';
  516.             $this->queryParser = new SparqlParser();
  517.         }
  518.         return $this->queryParser->parse($query);
  519.     }//function _parseSparqlQuery($query)
  520.  
  521. // end: Model
  522.  
  523. ?>

Documentation generated on Fri, 1 Jun 2007 16:49:52 +0200 by phpDocumentor 1.3.2