repositoryRedirectLookup = $repositoryRedirectLookup; $this->dataItemExportInMemoryCache = ApplicationFactory::getInstance()->getInMemoryPoolCache()->getPoolCacheById( self::POOLCACHE_ID ); } /** * @since 2.3 * * @param integer $chunkSize */ public function setTriplesChunkSize( $triplesChunkSize ) { $this->triplesChunkSize = (int)$triplesChunkSize; } /** * @since 2.0 * * @param SemanticData $semanticData */ public function doBuildTriplesFrom( SemanticData $semanticData ) { $this->hasTriplesForUpdate = false; $this->triples = ''; $this->prefixes = []; $this->doSerialize( $semanticData ); } /** * @since 2.0 * * @return boolean */ public function hasTriples() { return $this->hasTriplesForUpdate; } /** * @since 2.3 * * @return string */ public function getTriples() { return $this->triples === null ? '' : $this->triples; } /** * Split the triples into group of chunks as it can happen that some subjects * contain SPARQL strings that exceed 1800 lines which may reach the capacity * limit of a RespositoryConnector (#1110). * * @since 2.3 * * @return array */ public function getChunkedTriples() { $chunkedTriples = []; if ( $this->triples === null ) { return $chunkedTriples; } if ( strpos( $this->triples, " ." ) === false ) { return $chunkedTriples; } $triplesArrayChunks = array_chunk( explode( " .", $this->triples ), $this->triplesChunkSize ); foreach( $triplesArrayChunks as $triplesChunk ) { $chunkedTriples[] = implode( " .", $triplesChunk ) . "\n"; } return $chunkedTriples; } /** * @since 2.0 * * @return array */ public function getPrefixes() { return $this->prefixes; } /** * @since 2.0 */ public static function reset() { TurtleSerializer::reset(); } private function doSerialize( SemanticData $semanticData ) { $expDataArray = $this->prepareUpdateExpData( $semanticData ); if ( count( $expDataArray ) > 0 ) { $this->hasTriplesForUpdate = true; $turtleSerializer = new TurtleSerializer( true ); $turtleSerializer->startSerialization(); foreach ( $expDataArray as $expData ) { $turtleSerializer->serializeExpData( $expData ); } $turtleSerializer->finishSerialization(); $this->triples = $turtleSerializer->flushContent(); $this->prefixes = $turtleSerializer->flushSparqlPrefixes(); } } /** * Prepare an array of SMWExpData elements that should be written to * the SPARQL store. The result is empty if no updates should be done. * Note that this is different from writing an SMWExpData element that * has no content. * Otherwise, the first SMWExpData object in the array is a translation * of the given input data, but with redirects resolved. Further * SMWExpData objects might be included in the resulting list to * capture necessary stub declarations for objects that do not have * any data in the RDF store yet. * * @since 1.6 * * @param SemanticData $semanticData * * @return array of SMWExpData */ private function prepareUpdateExpData( SemanticData $semanticData ) { $result = []; $expData = Exporter::getInstance()->makeExportData( $semanticData ); $newExpData = $this->expandUpdateExpData( $expData, $result, false ); array_unshift( $result, $newExpData ); return $result; } /** * Find a normalized representation of the given SMWExpElement that can * be used in an update of the stored data. Normalization uses * redirects. The type of the ExpElement might change, especially into * SMWExpData in order to store auxiliary properties. * Moreover, the method records any auxiliary data that should be * written to the store when including this SMWExpElement into updates. * This auxiliary data is collected in a call-by-ref array. * * @since 1.6 * * @param Element $expElement object containing the update data * @param $auxiliaryExpData array of SMWExpData * * @return ExpElement */ private function expandUpdateExpElement( Element $expElement, array &$auxiliaryExpData ) { if ( $expElement instanceof ExpResource ) { return $this->expandUpdateExpResource( $expElement, $auxiliaryExpData ); } if ( $expElement instanceof ExpData ) { return $this->expandUpdateExpData( $expElement, $auxiliaryExpData, true ); } return $expElement; } /** * Find a normalized representation of the given SMWExpResource that can * be used in an update of the stored data. Normalization uses * redirects. The type of the ExpElement might change, especially into * SMWExpData in order to store auxiliary properties. * Moreover, the method records any auxiliary data that should be * written to the store when including this SMWExpElement into updates. * This auxiliary data is collected in a call-by-ref array. * * @since 1.6 * * @param ExpResource $expResource object containing the update data * @param $auxiliaryExpData array of SMWExpData * * @return ExpElement */ private function expandUpdateExpResource( ExpResource $expResource, array &$auxiliaryExpData ) { $exists = true; if ( $expResource instanceof ExpNsResource ) { $elementTarget = $this->repositoryRedirectLookup->findRedirectTargetResource( $expResource, $exists ); } else { $elementTarget = $expResource; } if ( !$exists && $elementTarget->getDataItem() instanceof DIWikiPage && $elementTarget->getDataItem()->getDBKey() !== '' ) { $diWikiPage = $elementTarget->getDataItem(); $hash = $diWikiPage->getHash(); if ( !$this->dataItemExportInMemoryCache->contains( $hash ) ) { $this->dataItemExportInMemoryCache->save( $hash, Exporter::getInstance()->makeExportDataForSubject( $diWikiPage, true ) ); } $auxiliaryExpData[$hash] = $this->dataItemExportInMemoryCache->fetch( $hash ); } return $elementTarget; } /** * Find a normalized representation of the given SMWExpData that can * be used in an update of the stored data. Normalization uses * redirects. * Moreover, the method records any auxiliary data that should be * written to the store when including this SMWExpElement into updates. * This auxiliary data is collected in a call-by-ref array. * * @since 1.6 * @param ExpData $expData object containing the update data * @param $auxiliaryExpData array of SMWExpData * @param $expandSubject boolean controls if redirects/auxiliary data should also be sought for subject * * @return ExpData */ private function expandUpdateExpData( ExpData $expData, array &$auxiliaryExpData, $expandSubject ) { $subjectExpResource = $expData->getSubject(); if ( $expandSubject ) { $expandedExpElement = $this->expandUpdateExpElement( $subjectExpResource, $auxiliaryExpData ); if ( $expandedExpElement instanceof ExpData ) { $newExpData = $expandedExpElement; } else { // instanceof SMWExpResource $newExpData = new ExpData( $subjectExpResource ); } } else { $newExpData = new ExpData( $subjectExpResource ); } foreach ( $expData->getProperties() as $propertyResource ) { $propertyTarget = $this->expandUpdateExpElement( $propertyResource, $auxiliaryExpData ); foreach ( $expData->getValues( $propertyResource ) as $element ) { $newExpData->addPropertyObjectValue( $propertyTarget, $this->expandUpdateExpElement( $element, $auxiliaryExpData ) ); } } return $newExpData; } }