r88884 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r88883‎ | r88884 | r88885 >
Date:11:30, 26 May 2011
Author:mkroetzsch
Status:deferred
Tags:
Comment:
enabled proper RDF export and storage for container data
Modified paths:
  • /trunk/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/export/SMW_Exporter.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/export/SMW_Serializer_RDFXML.php (modified) (history)
  • /trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SparqlStore.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticMediaWiki/includes/export/SMW_Serializer_RDFXML.php
@@ -120,7 +120,8 @@
121121 $this->post_ns_buffer .= "\t$indent<$type";
122122 }
123123
124 - if ( $expData->getSubject() instanceof SMWExpResource ) {
 124+ if ( ( $expData->getSubject() instanceof SMWExpResource ) &&
 125+ !$expData->getSubject()->isBlankNode() ) {
125126 $this->post_ns_buffer .= ' rdf:about="' . $expData->getSubject()->getUri() . '"';
126127 } // else: blank node, no "rdf:about"
127128
@@ -149,7 +150,7 @@
150151 if ( $collection !== false ) { // RDF-style collection (list)
151152 $this->serializeExpCollection( $property, $collection, "\t\t$indent", $isClassTypeProp );
152153 } elseif ( count( $valueElement->getProperties() ) > 0 ) { // resource with data
153 - $this->post_ns_buffer .= "\t\t$indent<" . $expResourceProperty->getQName() . ">\n";
 154+ $this->post_ns_buffer .= "\t\t$indent<" . $property->getQName() . ">\n";
154155 $this->serializeNestedExpData( $valueElement, "\t\t$indent" );
155156 $this->post_ns_buffer .= "\t\t$indent</" . $property->getQName() . ">\n";
156157 } else { // resource without data
Index: trunk/extensions/SemanticMediaWiki/includes/export/SMW_Exporter.php
@@ -76,7 +76,9 @@
7777 */
7878 static public function makeExportDataForSubject( SMWDIWikiPage $diWikiPage, $typesvalueforproperty = null, $addStubData = false ) {
7979 global $wgContLang;
80 - $result = new SMWExpData( self::getDataItemExpElement( $diWikiPage ) );
 80+ $wikiPageExpElement = self::getDataItemExpElement( $diWikiPage );
 81+ $result = new SMWExpData( $wikiPageExpElement );
 82+
8183 $pageTitle = str_replace( '_', ' ', $diWikiPage->getDBkey() );
8284 if ( $diWikiPage->getNamespace() !== 0 ) {
8385 $prefixedSubjectTitle = $wgContLang->getNsText( $diWikiPage->getNamespace()) . ":" . $pageTitle;
@@ -84,6 +86,7 @@
8587 $prefixedSubjectTitle = $pageTitle;
8688 }
8789 $prefixedSubjectUrl = wfUrlencode( str_replace( ' ', '_', $prefixedSubjectTitle ) );
 90+
8891 switch ( $diWikiPage->getNamespace() ) {
8992 case NS_CATEGORY: case SMW_NS_CONCEPT:
9093 $maintype_pe = self::getSpecialNsResource( 'owl', 'Class' );
@@ -101,19 +104,24 @@
102105 $label = $prefixedSubjectTitle;
103106 $maintype_pe = self::getSpecialNsResource( 'swivt', 'Subject' );
104107 }
105 - $ed = new SMWExpLiteral( $label );
106 - $result->addPropertyObjectValue( self::getSpecialNsResource( 'rdfs', 'label' ), $ed );
107 - $ed = new SMWExpResource( self::getNamespaceUri( 'wikiurl' ) . $prefixedSubjectUrl );
108 - $result->addPropertyObjectValue( self::getSpecialNsResource( 'swivt', 'page' ), $ed );
109 - $ed = new SMWExpResource( self::$m_exporturl . '/' . $prefixedSubjectUrl );
110 - $result->addPropertyObjectValue( self::getSpecialNsResource( 'rdfs', 'isDefinedBy' ), $ed );
 108+
111109 $result->addPropertyObjectValue( self::getSpecialNsResource( 'rdf', 'type' ), $maintype_pe );
112 - $ed = new SMWExpLiteral( $diWikiPage->getNamespace(), 'http://www.w3.org/2001/XMLSchema#integer' );
113 - $result->addPropertyObjectValue( self::getSpecialNsResource( 'swivt', 'wikiNamespace' ), $ed );
114 - if ( $addStubData ) {
115 - $defaultSortkey = new SMWExpLiteral( str_replace( '_', ' ', $diWikiPage->getDBkey() ) );
116 - $result->addPropertyObjectValue( self::getSpecialPropertyResource( '_SKEY' ), $defaultSortkey );
 110+
 111+ if ( !$wikiPageExpElement->isBlankNode() ) {
 112+ $ed = new SMWExpLiteral( $label );
 113+ $result->addPropertyObjectValue( self::getSpecialNsResource( 'rdfs', 'label' ), $ed );
 114+ $ed = new SMWExpResource( self::getNamespaceUri( 'wikiurl' ) . $prefixedSubjectUrl );
 115+ $result->addPropertyObjectValue( self::getSpecialNsResource( 'swivt', 'page' ), $ed );
 116+ $ed = new SMWExpResource( self::$m_exporturl . '/' . $prefixedSubjectUrl );
 117+ $result->addPropertyObjectValue( self::getSpecialNsResource( 'rdfs', 'isDefinedBy' ), $ed );
 118+ $ed = new SMWExpLiteral( $diWikiPage->getNamespace(), 'http://www.w3.org/2001/XMLSchema#integer' );
 119+ $result->addPropertyObjectValue( self::getSpecialNsResource( 'swivt', 'wikiNamespace' ), $ed );
 120+ if ( $addStubData ) {
 121+ $defaultSortkey = new SMWExpLiteral( str_replace( '_', ' ', $diWikiPage->getDBkey() ) );
 122+ $result->addPropertyObjectValue( self::getSpecialPropertyResource( '_SKEY' ), $defaultSortkey );
 123+ }
117124 }
 125+
118126 return $result;
119127 }
120128
@@ -248,6 +256,9 @@
249257 $namespace = $importValue->getNS();
250258 $namespaceId = $importValue->getNSID();
251259 $localName = $importValue->getLocalName();
 260+ } elseif ( self::isInternalObjectDiPage( $diWikiPage ) ) { // blank node
 261+ $localName = $namespace = $namespaceId = '';
 262+ $diWikiPage = null; // do not associate any wiki page with blank nodes
252263 } else {
253264 $localName = '';
254265 if ( $diWikiPage->getNamespace() == SMW_NS_PROPERTY ) {
@@ -256,7 +267,7 @@
257268 $localName = self::encodeURI( rawurlencode( $diWikiPage->getDBkey() ) );
258269 }
259270 if ( ( $localName == '' ) ||
260 - ( in_array( $localName[0], array( '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) ) ) ) {
 271+ ( in_array( $localName{0}, array( '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) ) ) ) {
261272 $namespace = self::getNamespaceUri( 'wiki' );
262273 $namespaceId = 'wiki';
263274 if ( $diWikiPage->getNamespace() !== 0 ) {
@@ -547,8 +558,7 @@
548559 /// TODO
549560 return null;
550561 case SMWDataItem::TYPE_CONTAINER:
551 - /// TODO
552 - return null;
 562+ return self::makeExportData( $dataItem->getSemanticData() );
553563 case SMWDataItem::TYPE_WIKIPAGE:
554564 return self::getResourceElementForWikiPage( $dataItem );
555565 case SMWDataItem::TYPE_CONCEPT:
@@ -606,4 +616,35 @@
607617 return ( $dataItemType == SMWDataItem::TYPE_TIME );
608618 }
609619
 620+ /**
 621+ * Create a dataitem of a wikipage that is used to represent internal
 622+ * objects. These objects are used as anonymous placeholders that are
 623+ * only defined by their context. In particular, no two distinct
 624+ * dataitems for this wiki page should be assumed to represent the same
 625+ * object.
 626+ *
 627+ * @return SMWDIWikiPage
 628+ */
 629+ static public function getInternalObjectDiPage() {
 630+ return new SMWDIWikiPage( 'SMWInternalObject', NS_SPECIAL, '' );
 631+ }
 632+
 633+ /**
 634+ * Check if the given wiki page represents an internal object. See
 635+ * SMWExporter::getInternalObjectDiPage() for details.
 636+ *
 637+ * @see SMWExporter::getInternalObjectDiPage()
 638+ * @param $diWikiPage SMWDIWikiPage
 639+ * @return boolean
 640+ */
 641+ static public function isInternalObjectDiPage( SMWDIWikiPage $diWikiPage ) {
 642+ if ( $diWikiPage->getNamespace() == NS_SPECIAL &&
 643+ $diWikiPage->getDBkey() == 'SMWInternalObject' &&
 644+ $diWikiPage->getInterwiki() == '' ) {
 645+ return true;
 646+ } else {
 647+ return false;
 648+ }
 649+ }
 650+
610651 }
Index: trunk/extensions/SemanticMediaWiki/includes/storage/SMW_SparqlStore.php
@@ -58,61 +58,148 @@
5959
6060 public function doDataUpdate( SMWSemanticData $data ) {
6161 parent::doDataUpdate( $data );
62 - $subjectResource = SMWExporter::getDataItemExpElement( $data->getSubject() );
63 - $this->deleteSparqlData( $subjectResource );
6462
6563 $expDataArray = $this->prepareUpdateExpData( $data );
6664
67 - $turtleSerializer = new SMWTurtleSerializer( true );
68 - $turtleSerializer->startSerialization();
69 - foreach ( $expDataArray as $expData ) {
70 - $turtleSerializer->serializeExpData( $expData );
 65+ if ( count( $expDataArray ) > 0 ) {
 66+ $subjectResource = SMWExporter::getDataItemExpElement( $data->getSubject() );
 67+ $this->deleteSparqlData( $subjectResource );
 68+
 69+ $turtleSerializer = new SMWTurtleSerializer( true );
 70+ $turtleSerializer->startSerialization();
 71+ foreach ( $expDataArray as $expData ) {
 72+ $turtleSerializer->serializeExpData( $expData );
 73+ }
 74+ $turtleSerializer->finishSerialization();
 75+ $triples = $turtleSerializer->flushContent();
 76+ $prefixes = $turtleSerializer->flushSparqlPrefixes();
 77+
 78+ smwfGetSparqlDatabase()->insertData( $triples, $prefixes );
7179 }
72 - $turtleSerializer->finishSerialization();
73 - $triples = $turtleSerializer->flushContent();
74 - $prefixes = $turtleSerializer->flushSparqlPrefixes();
75 -
76 - smwfGetSparqlDatabase()->insertData( $triples, $prefixes );
7780 }
7881
7982 /**
8083 * Prepare an array of SMWExpData elements that should be written to
81 - * the SPARQL store, or return null if no update should be performed.
 84+ * the SPARQL store. The result is empty if no updates should be done.
 85+ * Note that this is different from writing an SMWExpData element that
 86+ * has no content.
8287 * Otherwise, the first SMWExpData object in the array is a translation
83 - * of the given input data, but with redirects resolved.
 88+ * of the given input data, but with redirects resolved. Further
 89+ * SMWExpData objects might be included in the resulting list to
 90+ * capture necessary stub declarations for objects that do not have
 91+ * any data in the RDF store yet.
8492 *
8593 * @param $data SMWSemanticData object containing the update data
 94+ * @return array of SMWExpData
8695 */
8796 protected function prepareUpdateExpData( SMWSemanticData $data ) {
8897 $expData = SMWExporter::makeExportData( $data );
8998 $result = array();
90 - $newExpData = new SMWExpData( $expData->getSubject() );
91 - $exists = false;
 99+ $newExpData = $this->expandUpdateExpData( $expData, $expData->getSubject(), $result, false );
 100+ array_unshift( $result, $newExpData );
 101+ return $result;
 102+ }
 103+
 104+ /**
 105+ * Find a normalized representation of the given SMWExpElement that can
 106+ * be used in an update of the stored data. Normalization uses
 107+ * redirects. The type of the ExpElement might change, especially into
 108+ * SMWExpData in order to store auxiliary properties.
 109+ * Moreover, the method records any auxiliary data that should be
 110+ * written to the store when including this SMWExpElement into updates.
 111+ * This auxiliary data is collected in a call-by-ref array.
 112+ *
 113+ * @param $expElement SMWExpElement object containing the update data
 114+ * @param $masterExpElement SMWExpResource to which encountered blank nodes will be associated
 115+ * @param $auxiliaryExpData array of SMWExpData
 116+ * @return SMWExpElement
 117+ */
 118+ protected function expandUpdateExpElement( SMWExpElement $expElement, SMWExpResource $masterExpElement, array &$auxiliaryExpData ) {
 119+ if ( $expElement instanceof SMWExpResource ) {
 120+ $elementTarget = $this->expandUpdateExpResource( $expElement, $masterExpElement, $auxiliaryExpData );
 121+ } elseif ( $expElement instanceof SMWExpData ) {
 122+ $elementTarget = $this->expandUpdateExpData( $expElement, $masterExpElement, $auxiliaryExpData, true );
 123+ } else {
 124+ $elementTarget = $expElement;
 125+ }
 126+
 127+ return $elementTarget;
 128+ }
 129+
 130+ /**
 131+ * Find a normalized representation of the given SMWExpResource that can
 132+ * be used in an update of the stored data. Normalization uses
 133+ * redirects. The type of the ExpElement might change, especially into
 134+ * SMWExpData in order to store auxiliary properties.
 135+ * Moreover, the method records any auxiliary data that should be
 136+ * written to the store when including this SMWExpElement into updates.
 137+ * This auxiliary data is collected in a call-by-ref array.
 138+ *
 139+ * @param $expResource SMWExpResource object containing the update data
 140+ * @param $masterExpElement SMWExpResource to which encountered blank nodes will be associated
 141+ * @param $auxiliaryExpData array of SMWExpData
 142+ * @return SMWExpElement
 143+ */
 144+ protected function expandUpdateExpResource( SMWExpResource $expResource, SMWExpResource $masterExpElement, array &$auxiliaryExpData ) {
 145+ $exists = true;
 146+ if ( $expResource instanceof SMWExpNsResource ) {
 147+ $elementTarget = $this->getSparqlRedirectTarget( $expResource, $exists );
 148+ } else {
 149+ $elementTarget = $expResource;
 150+ }
 151+
 152+ if ( $elementTarget->isBlankNode() ) {
 153+ $auxExpData = new SMWExpData( $elementTarget );
 154+ $masterResourceProperty = SMWExporter::getSpecialNsResource( 'swivt', 'masterResource' );
 155+ $auxExpData->addPropertyObjectValue( $masterResourceProperty, $masterExpElement );
 156+ $elementTarget = $auxExpData;
 157+ } elseif ( !$exists && ( $elementTarget->getDataItem() instanceof SMWDIWikiPage ) ) {
 158+ $diWikiPage = $elementTarget->getDataItem();
 159+ $hash = $diWikiPage->getHash();
 160+ if ( !array_key_exists( $hash, $auxiliaryExpData ) ) {
 161+ $auxiliaryExpData[$hash] = SMWExporter::makeExportDataForSubject( $diWikiPage, null, true );
 162+ }
 163+ }
 164+
 165+ return $elementTarget;
 166+ }
 167+
 168+ /**
 169+ * Find a normalized representation of the given SMWExpData that can
 170+ * be used in an update of the stored data. Normalization uses
 171+ * redirects.
 172+ * Moreover, the method records any auxiliary data that should be
 173+ * written to the store when including this SMWExpElement into updates.
 174+ * This auxiliary data is collected in a call-by-ref array.
 175+ *
 176+ * @param $expData SMWExpData object containing the update data
 177+ * @param $masterExpElement SMWExpResource to which encountered blank nodes will be associated
 178+ * @param $auxiliaryExpData array of SMWExpData
 179+ * @param $expandSubject boolean controls if redirects/auxiliary data should also be sought for subject
 180+ * @return SMWExpData
 181+ */
 182+ protected function expandUpdateExpData( SMWExpData $expData, SMWExpResource $masterExpElement, array &$auxiliaryExpData, $expandSubject ) {
 183+ $subjectExpResource = $expData->getSubject();
 184+ if ( $expandSubject ) {
 185+ $expandedExpElement = $this->expandUpdateExpElement( $subjectExpResource, $masterExpElement, $auxiliaryExpData );
 186+ if ( $expandedExpElement instanceof SMWExpData ) {
 187+ $newExpData = $expandedExpElement;
 188+ } else { // instanceof SMWExpResource
 189+ $newExpData = new SMWExpData( $subjectExpResource );
 190+ }
 191+ } else {
 192+ $newExpData = new SMWExpData( $subjectExpResource );
 193+ }
 194+
92195 foreach ( $expData->getProperties() as $propertyResource ) {
93 - $propertyTarget = $this->getSparqlRedirectTarget( $propertyResource, $exists );
94 - if ( !$exists && ( $propertyResource->getDataItem() instanceof SMWDIWikiPage ) ) {
95 - $diWikiPage = $propertyResource->getDataItem();
96 - if ( ( $diWikiPage !== null ) && !array_key_exists( $diWikiPage->gethash(), $result ) ) {
97 - $result[$diWikiPage->gethash()] = SMWExporter::makeExportDataForSubject( $diWikiPage, null, true );
98 - }
99 - }
 196+ $propertyTarget = $this->expandUpdateExpElement( $propertyResource, $masterExpElement, $auxiliaryExpData );
100197 foreach ( $expData->getValues( $propertyResource ) as $expElement ) {
101 - if ( $expElement instanceof SMWExpNsResource ) {
102 - $elementTarget = $this->getSparqlRedirectTarget( $expElement, $exists );
103 - if ( !$exists && ( $expElement->getDataItem() instanceof SMWDIWikiPage ) ) {
104 - $diWikiPage = $expElement->getDataItem();
105 - if ( ( $diWikiPage !== null ) && !array_key_exists( $diWikiPage->gethash(), $result ) ) {
106 - $result[$diWikiPage->gethash()] = SMWExporter::makeExportDataForSubject( $diWikiPage, null, true );
107 - }
108 - }
109 - } else {
110 - $elementTarget = $expElement;
111 - }
 198+ $elementTarget = $this->expandUpdateExpElement( $expElement, $masterExpElement, $auxiliaryExpData );
112199 $newExpData->addPropertyObjectValue( $propertyTarget, $elementTarget );
113200 }
114201 }
115 - $result[] = $newExpData;
116 - return $result;
 202+
 203+ return $newExpData;
117204 }
118205
119206 /**
@@ -122,10 +209,16 @@
123210 * used for making a resource with a prefix).
124211 *
125212 * @param $expNsResource string URI to check
126 - * @param $exists boolean that is set to true if $expNsResource is in the store
 213+ * @param $exists boolean that is set to true if $expNsResource is in the
 214+ * store; always false for blank nodes
127215 * @return SMWExpNsResource
128216 */
129217 protected function getSparqlRedirectTarget( SMWExpNsResource $expNsResource, &$exists ) {
 218+ if ( $expNsResource->isBlankNode() ) {
 219+ $exists = false;
 220+ return $expNsResource;
 221+ }
 222+
130223 $resourceUri = SMWTurtleSerializer::getTurtleNameForExpElement( $expNsResource );
131224 $rediUri = SMWTurtleSerializer::getTurtleNameForExpElement( SMWExporter::getSpecialPropertyResource( '_REDI' ) );
132225 $skeyUri = SMWTurtleSerializer::getTurtleNameForExpElement( SMWExporter::getSpecialPropertyResource( '_SKEY' ) );
@@ -143,7 +236,7 @@
144237 $exists = true;
145238 $rediTargetElement = $firstRow[1];
146239 $rediTargetUri = $rediTargetElement->getUri();
147 - $wikiNamespace = Exporter::expandUri( '$wiki;' );
 240+ $wikiNamespace = Exporter::getNamespaceUri( 'wiki' );
148241 if ( strpos( $rediTargetUri, $wikiNamespace ) === 0 ) {
149242 return new SMWExpNsResource( substr( $rediTargetUri, 0, strlen( $wikiNamespace ) ) , $wikiNamespace, 'wiki' );
150243 } else {
Index: trunk/extensions/SemanticMediaWiki/includes/dataitems/SMW_DI_Container.php
@@ -31,7 +31,7 @@
3232 * @param boolean $noDuplicates stating if duplicate data should be avoided
3333 */
3434 public function __construct( $noDuplicates = true ) {
35 - $subject = new SMWDIWikiPage( 'SMWInternalObject', NS_SPECIAL, '' ); // dummy subject
 35+ $subject = SMWExporter::getInternalObjectDiPage();
3636 parent::__construct( $subject, $noDuplicates );
3737 }
3838

Status & tagging log