/** * @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; }
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; }