/**
 * @file
 * @ingroup SMWHaloTriplestore
 * 
 * Simple contributor only updates the 'has type' annotations.
 *
 * Called when property annotations get updated in a triple store.
 *
 * @param $semData All semantic data (for context)
 * @param $property Currently processed property
 * @param $propertyValueArray Values of current property
 * @param $triplesFromHook Triples which are returned.
 *
 * @return Array of triples or false. If return value is a non-empty array processing stops for this property. Same if it is explicitly false.
 * Otherwise normal processing goes on.
 */
function smwfTripleStorePropertyUpdate(&$data, &$property, &$propertyValueArray, &$triplesFromHook)
{
    global $smwgTripleStoreGraph;
    if (!$property instanceof SMWPropertyValue) {
        // error. should not happen
        trigger_error("Triple store update: property is not SMWPropertyValue");
        return true;
    }
    // check if it is a property with special semantics
    // check for 'has domain, range' and 'is inverse of' and 'has type'
    // 'has min cardinality' and 'has max cardinality are read implictly when processing 'has domain and range'
    // and therefore ignored.
    $allProperties = $data->getProperties();
    if (smwfGetSemanticStore()->inverseOf->getDBkey() == array_shift($property->getDBkeys())) {
        foreach ($propertyValueArray as $inverseProps) {
            if (count($propertyValueArray) == 1) {
                $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "owl:inverseOf", "<{$smwgTripleStoreGraph}/property#" . $inverseProps->getDBkey() . ">");
            }
        }
    } elseif ($property->getPropertyID() == "_TYPE") {
        // insert RDFS range/domain
        foreach ($propertyValueArray as $value) {
            $typeID = array_shift($value->getDBkeys());
            if ($typeID != '_wpg') {
                $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#Has_type>", WikiTypeToXSD::getXSDType($typeID));
            }
        }
    }
    return true;
}
/**
 * @file
 * @ingroup SMWHaloTriplestore
 * 
 * Schema contributor tries to add all schema information from the wiki
 * Warning: may created complex models.
 * 
 * Called when property annotations get updated in a triple store.
 *
 * @param $semData All semantic data (for context)
 * @param $property Currently processed property
 * @param $propertyValueArray Values of current property
 * @param $triplesFromHook Triples which are returned.
 *
 * @return Array of triples or false. If return value is a non-empty array processing stops for this property. Same if it is explicitly false.
 * Otherwise normal processing goes on.
 */
function smwfTripleStorePropertyUpdate(&$data, &$property, &$propertyValueArray, &$triplesFromHook)
{
    global $smwgTripleStoreGraph;
    if (!$property instanceof SMWPropertyValue) {
        // error. should not happen
        trigger_error("Triple store update: property is not SMWPropertyValue");
        return true;
    }
    // check if it is a property with special semantics
    // check for 'has domain, range' and 'is inverse of' and 'has type'
    // 'has min cardinality' and 'has max cardinality are read implictly when processing 'has domain and range'
    // and therefore ignored.
    $allProperties = $data->getProperties();
    if (smwfGetSemanticStore()->domainRangeHintRelation->getDBkey() == array_shift($property->getDBkeys())) {
        foreach ($propertyValueArray as $domRange) {
            if (!$domRange instanceof SMWRecordValue) {
                continue;
            }
            // occurs if 'has domain and range' is not n-ary
            if (count($domRange->getDVs()) == 2) {
                $dvs = $domRange->getDVs();
                if ($dvs[0] != NULL && $dvs[1] != NULL && $dvs[0]->isValid() && $dvs[1]->isValid()) {
                    // domain and range
                    $minCard = $data->getPropertyValues(smwfGetSemanticStore()->minCardProp);
                    $maxCard = $data->getPropertyValues(smwfGetSemanticStore()->maxCardProp);
                    // insert RDFS
                    $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "rdfs:domain", "cat:" . $dvs[0]->getDBkey());
                    $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "rdfs:range", "cat:" . $dvs[1]->getDBkey());
                    // insert OWL
                    $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/category#" . $dvs[0]->getDBkey() . ">", "rdfs:subClassOf", "_:1");
                    $triplesFromHook[] = array("_:1", "owl:Restriction", "_:2");
                    $triplesFromHook[] = array("_:2", "owl:onProperty", "<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">");
                    $triplesFromHook[] = array("_:2", "owl:allValuesFrom", "<{$smwgTripleStoreGraph}/category#" . $dvs[1]->getDBkey() . ">");
                    foreach ($minCard as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $triplesFromHook[] = array("_:2", "owl:minCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                        }
                    }
                    foreach ($maxCard as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $triplesFromHook[] = array("_:2", "owl:minCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                        }
                    }
                } elseif ($dvs[0] != NULL && $dvs[0]->isValid()) {
                    // only domain
                    $typeValues = $data->getPropertyValues(SMWPropertyValue::makeProperty("_TYPE"));
                    $minCard = $data->getPropertyValues(smwfGetSemanticStore()->minCardProp);
                    $maxCard = $data->getPropertyValues(smwfGetSemanticStore()->maxCardProp);
                    // insert RDFS
                    $triplesFromHook[] = array("prop:" . $data->getSubject()->getDBkey(), "rdfs:domain", "<{$smwgTripleStoreGraph}/category#" . $dvs[0]->getDBkey() . ">");
                    foreach ($typeValues as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $typeID = array_shift($value->getDBkeys());
                            if ($typeID != '_wpg') {
                                $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "rdfs:range", WikiTypeToXSD::getXSDType($typeID));
                            }
                        }
                    }
                    // insert OWL
                    $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/category#" . $dvs[0]->getDBkey() . ">", "rdfs:subClassOf", "_:1");
                    $triplesFromHook[] = array("_:1", "owl:Restriction", "_:2");
                    $triplesFromHook[] = array("_:2", "owl:onProperty", "<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">");
                    foreach ($typeValues as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $triplesFromHook[] = array("_:2", "owl:allValuesFrom", WikiTypeToXSD::getXSDType(array_shift($value->getDBkeys())));
                        }
                    }
                    foreach ($minCard as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $triplesFromHook[] = array("_:2", "owl:minCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                        }
                    }
                    foreach ($maxCard as $value) {
                        if (array_shift($value->getDBkeys()) !== false) {
                            $triplesFromHook[] = array("_:2", "owl:maxCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                        }
                    }
                }
            }
        }
    } elseif (smwfGetSemanticStore()->inverseOf->getDBkey() == array_shift($property->getDBkeys())) {
        foreach ($propertyValueArray as $inverseProps) {
            if (count($propertyValueArray) == 1) {
                $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "owl:inverseOf", "<{$smwgTripleStoreGraph}/property#" . $inverseProps->getDBkey() . ">");
            }
        }
    } elseif (smwfGetSemanticStore()->minCard->getDBkey() == array_shift($property->getDBkeys())) {
        // do nothing
        $triplesFromHook = false;
    } elseif (smwfGetSemanticStore()->maxCard->getDBkey() == array_shift($property->getDBkeys())) {
        // do nothing
        $triplesFromHook = false;
    } elseif ($property->getPropertyID() == "_TYPE") {
        // serialize type only if there is no domain and range annotation
        $domRanges = $data->getPropertyValues(smwfGetSemanticStore()->domainRangeHintProp);
        if (count($domRanges) == 0) {
            // insert only if domain and range annotation does not exist
            // insert OWL restrictions
            $minCard = $data->getPropertyValues(smwfGetSemanticStore()->minCardProp);
            $maxCard = $data->getPropertyValues(smwfGetSemanticStore()->maxCardProp);
            $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#DefaultRootCategory>", "rdfs:subClassOf", "_:1");
            $triplesFromHook[] = array("_:1", "owl:Restriction", "_:2");
            $triplesFromHook[] = array("_:2", "owl:onProperty", "<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">");
            foreach ($propertyValueArray as $value) {
                if (array_shift($value->getDBkeys()) !== false) {
                    $typeID = array_shift($value->getDBkeys());
                    $triplesFromHook[] = array("_:2", "owl:allValuesFrom", WikiTypeToXSD::getXSDType($typeID));
                }
            }
            foreach ($minCard as $value) {
                if (array_shift($value->getDBkeys()) !== false) {
                    $triplesFromHook[] = array("_:2", "owl:minCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                }
            }
            foreach ($maxCard as $value) {
                if (array_shift($value->getDBkeys()) !== false) {
                    $triplesFromHook[] = array("_:2", "owl:maxCardinality", "\"" . array_shift($value->getDBkeys()) . "\"");
                }
            }
            // insert RDFS range/domain
            foreach ($propertyValueArray as $value) {
                $typeID = array_shift($value->getDBkeys());
                //$triplesFromHook[] = array("prop:".$data->getSubject()->getDBkey(), "rdfs:domain", "cat:DefaultRootCategory");
                if ($typeID != '_wpg') {
                    $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "rdfs:range", WikiTypeToXSD::getXSDType($typeID));
                }
            }
        }
        // insert Has type
        foreach ($propertyValueArray as $value) {
            $typeID = array_shift($value->getDBkeys());
            if ($typeID != '_wpg') {
                $triplesFromHook[] = array("<{$smwgTripleStoreGraph}/property#" . $data->getSubject()->getDBkey() . ">", "Has_type", WikiTypeToXSD::getXSDType($typeID));
            }
        }
    }
    return true;
}
Beispiel #3
0
 function updateData(SMWSemanticData $data)
 {
     $this->smwstore->updateData($data);
     $triples = array();
     $subject = $data->getSubject();
     // check for selective updates, ie. update only certain namespaces
     global $smwgUpdateTSOnNamespaces;
     if (isset($smwgUpdateTSOnNamespaces) && is_array($smwgUpdateTSOnNamespaces)) {
         if (!in_array($subject->getNamespace(), $smwgUpdateTSOnNamespaces)) {
             return;
         }
     }
     $subj_ns = $this->tsNamespace->getNSPrefix($subject->getNamespace());
     //properties
     global $smwgTripleStoreGraph;
     foreach ($data->getProperties() as $key => $property) {
         $propertyValueArray = $data->getPropertyValues($property);
         $triplesFromHook = array();
         wfRunHooks('TripleStorePropertyUpdate', array(&$data, &$property, &$propertyValueArray, &$triplesFromHook));
         if ($triplesFromHook === false || count($triplesFromHook) > 0) {
             $triples = is_array($triplesFromHook) ? array_merge($triples, $triplesFromHook) : $triples;
             continue;
             // do not process normal triple generation, if hook provides triples.
         }
         // handle properties with special semantics
         if ($property->getPropertyID() == "_TYPE") {
             // ingore. handeled by SMW_TS_SchemaContributor or SMW_TS_SimpleContributor
             continue;
         } elseif ($property->getPropertyID() == "_CONV") {
             // ingore. handeled by category section below
             global $smwgContLang;
             $specialProperties = $smwgContLang->getPropertyLabels();
             $conversionPropertyLabel = str_replace(" ", "_", $specialProperties['_CONV']);
             if ($subject->getNamespace() == SMW_NS_TYPE) {
                 foreach ($propertyValueArray as $value) {
                     // parse conversion annotation format
                     $measures = explode(",", array_shift($value->getDBkeys()));
                     // parse linear factor followed by (first) unit
                     $firstMeasure = reset($measures);
                     $indexOfWhitespace = strpos($firstMeasure, " ");
                     if ($indexOfWhitespace === false) {
                         continue;
                     }
                     // not a valid measure, ignore
                     $factor = trim(substr($firstMeasure, 0, $indexOfWhitespace));
                     $unit = trim(substr($firstMeasure, $indexOfWhitespace));
                     $triples[] = array("<{$smwgTripleStoreGraph}/type#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $conversionPropertyLabel . ">", "\"{$factor} {$unit}\"");
                     // add all aliases for this conversion factor using the same factor
                     $nextMeasure = next($measures);
                     while ($nextMeasure !== false) {
                         $nextMeasure = str_replace('"', '\\"', $nextMeasure);
                         $triples[] = array("<{$smwgTripleStoreGraph}/type#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $conversionPropertyLabel . ">", "\"{$factor} " . trim($nextMeasure) . "\"");
                         $nextMeasure = next($measures);
                     }
                 }
             }
             continue;
         } elseif ($property->getPropertyID() == "_INST") {
             // ingore. handeled by category section below
             continue;
         } elseif ($property->getPropertyID() == "_SUBC") {
             // ingore. handeled by category section below
             continue;
         } elseif ($property->getPropertyID() == "_REDI") {
             // ingore. handeled by redirect section below
             continue;
         } elseif ($property->getPropertyID() == "_SUBP") {
             if ($subject->getNamespace() == SMW_NS_PROPERTY) {
                 foreach ($propertyValueArray as $value) {
                     $triples[] = array("<{$smwgTripleStoreGraph}/property#" . $subject->getDBkey() . ">", "rdfs:subPropertyOf", "<{$smwgTripleStoreGraph}/property#" . $value->getDBkey() . ">");
                 }
             }
             continue;
         }
         // there are other special properties which need not to be handled special
         // so they can be handled by the default machanism:
         foreach ($propertyValueArray as $value) {
             if ($value->isValid()) {
                 if ($value->getTypeID() == '_txt') {
                     $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "\"" . $this->escapeForStringLiteral(array_shift($value->getDBkeys())) . "\"^^xsd:string");
                 } elseif ($value->getTypeID() == '_wpg' || $value->getTypeID() == '_wpp' || $value->getTypeID() == '_wpc' || $value->getTypeID() == '_wpf') {
                     $obj_ns = $this->tsNamespace->getNSPrefix($value->getNamespace());
                     $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "<{$smwgTripleStoreGraph}/{$obj_ns}#" . $value->getDBkey() . ">");
                 } elseif ($value->getTypeID() == '_rec') {
                     continue;
                     // do not add records (aka nary properties)
                 } else {
                     if ($value->getUnit() != '') {
                         // attribute with unit value
                         $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "\"" . array_shift($value->getDBkeys()) . " " . $value->getUnit() . "\"^^xsd:unit");
                     } else {
                         if (!is_null($property->getWikiPageValue())) {
                             if (array_shift($value->getDBkeys()) != NULL) {
                                 // attribute with textual value
                                 $xsdType = WikiTypeToXSD::getXSDType($property->getPropertyTypeID());
                                 if ($property->getPropertyTypeID() == '_geo') {
                                     $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "\"" . $this->escapeForStringLiteral(implode(",", $value->getDBkeys())) . "\"^^{$xsdType}");
                                 } else {
                                     $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "\"" . $this->escapeForStringLiteral(array_shift($value->getDBkeys())) . "\"^^{$xsdType}");
                                 }
                             } else {
                                 if ($value->getNumericValue() != NULL) {
                                     // attribute with numeric value
                                     $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "<{$smwgTripleStoreGraph}/property#" . $property->getWikiPageValue()->getDBkey() . ">", "\"" . $value->getNumericValue() . "\"^^xsd:double");
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // categories
     $categories = self::$fullSemanticData->getCategories();
     if ($subject->getNamespace() == NS_CATEGORY) {
         foreach ($categories as $c) {
             if ($c == NULL) {
                 continue;
             }
             $triplesFromHook = array();
             wfRunHooks('TripleStoreCategoryUpdate', array(&$subject, &$c, &$triplesFromHook));
             if ($triplesFromHook === false || count($triplesFromHook) > 0) {
                 $triples = is_array($triplesFromHook) ? array_merge($triples, $triplesFromHook) : $triples;
                 continue;
             }
             $triples[] = array("<{$smwgTripleStoreGraph}/category#" . $subject->getDBkey() . ">", "rdfs:subClassOf", "<{$smwgTripleStoreGraph}/category#" . $c->getDBkey() . ">");
         }
     } else {
         foreach ($categories as $c) {
             if ($c == NULL) {
                 continue;
             }
             $triplesFromHook = array();
             wfRunHooks('TripleStoreCategoryUpdate', array(&$subject, &$c, &$triplesFromHook));
             if ($triplesFromHook === false || count($triplesFromHook) > 0) {
                 $triples = is_array($triplesFromHook) ? array_merge($triples, $triplesFromHook) : $triples;
                 continue;
             }
             $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", "rdf:type", "<{$smwgTripleStoreGraph}/category#" . $c->getDBkey() . ">");
         }
     }
     // rules
     global $smwgEnableObjectLogicRules;
     if (isset($smwgEnableObjectLogicRules)) {
         $new_rules = self::$fullSemanticData->getRules();
         $old_rules = SMWRuleStore::getInstance()->getRules($subject->getArticleId());
         SMWRuleStore::getInstance()->clearRules($subject->getArticleId());
         SMWRuleStore::getInstance()->addRules($subject->getArticleId(), $new_rules);
     }
     // redirects
     $redirects = self::$fullSemanticData->getRedirects();
     foreach ($redirects as $r) {
         switch ($subj_ns) {
             case SMW_NS_PROPERTY:
                 $prop = "owl:equivalentProperty";
             case NS_CATEGORY:
                 $prop = "owl:equivalentClass";
             case NS_MAIN:
                 $prop = "owl:sameAs";
             default:
                 continue;
         }
         $r_ns = $this->tsNamespace->getNSPrefix($r->getNamespace());
         $triples[] = array("<{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . ">", $prop, "<{$smwgTripleStoreGraph}/{$r_ns}#" . $r->getDBkey() . ">");
     }
     // connect to MessageBroker and send commands
     global $smwgMessageBroker, $smwgTripleStoreGraph;
     try {
         $con = TSConnection::getConnector();
         $sparulCommands = array();
         $sparulCommands[] = TSNamespaces::getW3CPrefixes() . "DELETE FROM <{$smwgTripleStoreGraph}> { <{$smwgTripleStoreGraph}/{$subj_ns}#" . $subject->getDBkey() . "> ?p ?o. }";
         $sparulCommands[] = TSNamespaces::getW3CPrefixes() . "INSERT INTO <{$smwgTripleStoreGraph}> { " . $this->implodeTriples($triples) . " }";
         if (isset($smwgEnableObjectLogicRules)) {
             // delete old rules...
             foreach ($old_rules as $ruleID) {
                 $sparulCommands[] = "DELETE RULE {$ruleID} FROM <{$smwgTripleStoreGraph}>";
             }
             // ...and add new
             foreach ($new_rules as $rule) {
                 // The F-Logic parser does not accept linebreaks
                 // => remove them
                 list($ruleID, $ruleText, $native, $active, $type) = $rule;
                 $ruleText = preg_replace("/[\n\r]/", " ", $ruleText);
                 $nativeText = $native ? "NATIVE" : "";
                 $activeText = !$active ? "INACTIVE" : "";
                 $sparulCommands[] = "INSERT {$nativeText} {$activeText} RULE {$ruleID} INTO <{$smwgTripleStoreGraph}> : \"" . $this->escapeForStringLiteral($ruleText) . "\" TYPE \"{$type}\"";
             }
         }
         $con->connect();
         $con->update("/topic/WIKI.TS.UPDATE", $sparulCommands);
         $con->disconnect();
     } catch (Exception $e) {
         // print something??
     }
 }
 /**
  * @see superclass
  */
 function getPropertySubjects(SMWPropertyValue $property, $value, $requestoptions = NULL)
 {
     if (!$property->isUserDefined()) {
         return parent::getPropertySubjects($property, $value, $requestoptions);
     }
     if (smwfCheckIfPredefinedSMWHaloProperty($property)) {
         return parent::getPropertyValues($subject, $property, $requestoptions, $outputformat);
     }
     global $smwgTripleStoreGraph;
     $client = TSConnection::getConnector();
     $client->connect();
     $values = array();
     $propertyName = $property->getWikiPageValue()->getTitle()->getDBkey();
     $limit = isset($requestoptions->limit) ? " LIMIT " . $requestoptions->limit : "";
     $offset = isset($requestoptions->offset) ? " OFFSET " . $requestoptions->offset : "";
     $nsPrefixProp = $this->tsNamespace->getNSPrefix($property->getWikiPageValue()->getTitle()->getNamespace());
     try {
         if (is_null($value)) {
             $response = $client->query("SELECT ?s WHERE { GRAPH ?g { ?s <{$smwgTripleStoreGraph}/{$nsPrefixProp}#{$propertyName}> ?o. } } {$limit} {$offset}", "merge=false|graph={$smwgTripleStoreGraph}");
         } else {
             if ($value instanceof SMWWikiPageValue) {
                 $objectName = $value->getTitle()->getDBkey();
                 $nsPrefixObj = $this->tsNamespace->getNSPrefix($value->getTitle()->getNamespace());
                 $response = $client->query("SELECT ?s WHERE { GRAPH ?g { ?s <{$smwgTripleStoreGraph}/{$nsPrefixProp}#{$propertyName}> <{$smwgTripleStoreGraph}/{$nsPrefixObj}#{$objectName}>. } } {$limit} {$offset}", "merge=false");
             } else {
                 $objectvalue = str_replace('"', '\\"', array_shift($value->getDBkeys()));
                 $objecttype = WikiTypeToXSD::getXSDType($value->getTypeID());
                 $response = $client->query("SELECT ?s WHERE { GRAPH ?g { ?s <{$smwgTripleStoreGraph}/{$nsPrefixProp}#{$propertyName}> \"{$objectvalue}\"^^{$objecttype}. } } {$limit} {$offset}", "merge=false");
             }
         }
     } catch (Exception $e) {
         wfDebug("Triplestore does probably not run.\n");
         $response = TSNamespaces::$EMPTY_SPARQL_XML;
     }
     // query
     global $smwgSPARQLResultEncoding;
     // PHP strings are always interpreted in ISO-8859-1 but may be actually encoded in
     // another charset.
     if (isset($smwgSPARQLResultEncoding) && $smwgSPARQLResultEncoding == 'UTF-8') {
         $response = utf8_decode($response);
     }
     $dom = simplexml_load_string($response);
     $annotations = array();
     $results = $dom->xpath('//result');
     foreach ($results as $r) {
         $children = $r->children();
         // binding nodes
         $b = $children->binding[0];
         // predicate
         $sv = $b->children()->uri[0];
         $title = $this->getTitleFromURI((string) $sv);
         $value = SMWWikiPageValue::makePage($title->getDBkey(), $title->getNamespace());
         $metadata = $sv->attributes();
         foreach ($metadata as $mdProperty => $mdValue) {
             if (strpos($mdProperty, "_meta_") === 0) {
                 $value->setMetadata(substr($mdProperty, 6), explode("|||", $mdValue));
             }
         }
         $values[] = $value;
     }
     return $values;
 }