Ladsgroup has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/340696 )

Change subject: Add EntityRdfBuilderFactory and DispatchingEntityRdfBuilder.
......................................................................

Add EntityRdfBuilderFactory and DispatchingEntityRdfBuilder.

Bug: T157311
Change-Id: Id5920889655136cf06800ca92d06edda4551813e
---
M lib/includes/EntityTypeDefinitions.php
M lib/tests/phpunit/EntityTypeDefinitionsTest.php
A repo/includes/Rdf/DispatchingEntityRdfBuilder.php
A repo/includes/Rdf/EntityRdfBuilderFactory.php
M repo/includes/WikibaseRepo.php
A repo/tests/phpunit/includes/Rdf/DispatchingEntityRdfBuilderTest.php
A repo/tests/phpunit/includes/Rdf/EntityRdfBuilderFactoryTest.php
7 files changed, 338 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikibase 
refs/changes/96/340696/1

diff --git a/lib/includes/EntityTypeDefinitions.php 
b/lib/includes/EntityTypeDefinitions.php
index 336f534..12e3453 100644
--- a/lib/includes/EntityTypeDefinitions.php
+++ b/lib/includes/EntityTypeDefinitions.php
@@ -164,4 +164,13 @@
                return $this->getMapForDefinitionField( 
'changeop-deserializer-callback' );
        }
 
+       /**
+        * @return callable[] An array mapping entity type identifiers
+        * to callables instantiating EntityRdfBuilder objects
+        * Not guaranteed to contain all entity types.
+        */
+       public function getRdfBuilderFactoryCallbacks() {
+               return $this->getMapForDefinitionField( 
'rdf-builder-factory-callback' );
+       }
+
 }
diff --git a/lib/tests/phpunit/EntityTypeDefinitionsTest.php 
b/lib/tests/phpunit/EntityTypeDefinitionsTest.php
index 45ab259..1110cb6 100644
--- a/lib/tests/phpunit/EntityTypeDefinitionsTest.php
+++ b/lib/tests/phpunit/EntityTypeDefinitionsTest.php
@@ -31,7 +31,8 @@
                                'entity-id-pattern' => 'foo-id-pattern',
                                'entity-id-builder' => 'new-foo-id',
                                'entity-id-composer-callback' => 
'new-composed-foo-id',
-                               'changeop-deserializer-callback' => 
'new-changeop-deserializer-callback'
+                               'changeop-deserializer-callback' => 
'new-changeop-deserializer-callback',
+                               'rdf-builder-factory-callback' => 
'new-rdf-builder-factory-callback'
                        ),
                        'bar' => array(
                                'serializer-factory-callback' => 
'bar-serializer',
@@ -166,4 +167,13 @@
                );
        }
 
+       public function testGetRdfBuilderFactoryCallbacks() {
+               $definitions = new EntityTypeDefinitions( 
$this->getDefinitions() );
+
+               $this->assertSame(
+                       [ 'foo' => 'new-rdf-builder-factory-callback' ],
+                       $definitions->getRdfBuilderFactoryCallbacks()
+               );
+       }
+
 }
diff --git a/repo/includes/Rdf/DispatchingEntityRdfBuilder.php 
b/repo/includes/Rdf/DispatchingEntityRdfBuilder.php
new file mode 100644
index 0000000..4a3403d
--- /dev/null
+++ b/repo/includes/Rdf/DispatchingEntityRdfBuilder.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Wikibase\Rdf;
+
+use Wikibase\DataModel\Entity\EntityDocument;
+use Wikimedia\Assert\Assert;
+
+/**
+ * Dispatching implementation of EntityRdfBuilder. This allows extensions to 
register
+ * EntityRdfBuilders for custom data types.
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani
+ */
+class DispatchingEntityRdfBuilder implements EntityRdfBuilder {
+
+       /**
+        * @var EntityRdfBuilder[]
+        */
+       private $rdfBuilders;
+
+       /**
+        * @param EntityRdfBuilder[] $rdfBuilders EntityRdfBuilder objects 
keyed by entity type
+        */
+       public function __construct( array $rdfBuilders ) {
+               Assert::parameterElementType( EntityRdfBuilder::class, 
$rdfBuilders, '$rdfBuilders' );
+
+               $this->rdfBuilders = $rdfBuilders;
+       }
+
+       /**
+        * Adds specific entity
+        *
+        * @param EntityDocument $entity
+        */
+       public function addEntity(
+               EntityDocument $entity
+       ) {
+               $builder = $this->getRdfBuilder( $entity->getType() );
+
+               if ( $builder ) {
+                       $builder->addEntity( $entity );
+               }
+       }
+
+       /**
+        * @param string $entityType
+        *
+        * @return null|EntityRdfBuilder
+        */
+       private function getRdfBuilder( $entityType ) {
+               if ( $entityType !== null ) {
+                       if ( isset( $this->rdfBuilders[$entityType] ) ) {
+                               return $this->rdfBuilders[$entityType];
+                       }
+               }
+
+               wfLogWarning( __METHOD__ . ": No RDF builder defined for entity 
type $entityType." );
+               return null;
+       }
+
+}
diff --git a/repo/includes/Rdf/EntityRdfBuilderFactory.php 
b/repo/includes/Rdf/EntityRdfBuilderFactory.php
new file mode 100644
index 0000000..04ec52e
--- /dev/null
+++ b/repo/includes/Rdf/EntityRdfBuilderFactory.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Wikibase\Rdf;
+
+use Wikimedia\Assert\Assert;
+use Wikimedia\Purtle\RdfWriter;
+
+/**
+ * Factory for ValueSnakRdfBuilder based on factory callbacks.
+ * For use with DataTypeDefinitions.
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani <ladsgr...@gmail.com>
+ */
+class EntityRdfBuilderFactory {
+
+       /**
+        * @var callable[]
+        */
+       private $factoryCallbacks;
+
+       /**
+        * @param callable[] $factoryCallbacks Factory callback functions as 
returned by
+        *        EntityTypeDefinitions::getRdfBuilderFactoryCallbacks(). 
Callbacks will be invoked
+        *        with the signature ($mode, RdfVocabulary, 
EntityMentionListener) and must
+        *        return a EntityRdfBuilder (or null).
+        */
+       public function __construct( array $factoryCallbacks ) {
+               Assert::parameterElementType( 'callable', $factoryCallbacks, 
'$factoryCallbacks' );
+
+               $this->factoryCallbacks = $factoryCallbacks;
+       }
+
+       /**
+        * Returns an EntityRdfBuilder for reified value output.
+        *
+        * @param int                   $flavorFlags Flavor flags to use for 
the entity rdf builder
+        * @param RdfVocabulary         $vocabulary
+        * @param RdfWriter             $writer
+        * @param EntityMentionListener $mentionedEntityTracker
+        * @param DedupeBag             $dedupe
+        * @return DispatchingEntityRdfBuilder
+        */
+       public function getEntityRdfBuilder(
+               $flavorFlags,
+               RdfVocabulary $vocabulary,
+               RdfWriter $writer,
+               EntityMentionListener $mentionedEntityTracker,
+               DedupeBag $dedupe
+       ) {
+               $builders = $this->createEntityRdfBuilders(
+                       $flavorFlags,
+                       $vocabulary,
+                       $writer,
+                       $mentionedEntityTracker,
+                       $dedupe
+               );
+
+               return new DispatchingEntityRdfBuilder( $builders );
+       }
+
+       /**
+        * @param int                   $flavorFlags Flavor flags to use for 
the entity rdf builder
+        * @param RdfVocabulary         $vocabulary
+        * @param RdfWriter             $writer
+        * @param EntityMentionListener $mentionedEntityTracker
+        * @param DedupeBag             $dedupe
+        *
+        * @return EntityRdfBuilder[]
+        */
+       private function createEntityRdfBuilders(
+               $flavorFlags,
+               RdfVocabulary $vocabulary,
+               RdfWriter $writer,
+               EntityMentionListener $mentionedEntityTracker,
+               DedupeBag $dedupe
+       ) {
+               $builders = [];
+
+               foreach ( $this->factoryCallbacks as $key => $callback ) {
+                       $builder = call_user_func(
+                               $callback,
+                               $flavorFlags,
+                               $vocabulary,
+                               $writer,
+                               $mentionedEntityTracker,
+                               $dedupe
+                       );
+
+                       if ( $builder instanceof EntityRdfBuilder ) {
+                               $builders[$key] = $builder;
+                       }
+               }
+
+               return $builders;
+       }
+
+}
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index da724a6..a6fa8f6 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -84,6 +84,7 @@
 use Wikibase\Lib\Store\EntityRevisionLookup;
 use Wikibase\Lib\Store\EntityStore;
 use Wikibase\Lib\Store\EntityStoreWatcher;
+use Wikibase\Rdf\EntityRdfBuilderFactory;
 use Wikibase\Repo\Store\EntityTitleStoreLookup;
 use Wikibase\Lib\Store\LanguageFallbackLabelDescriptionLookupFactory;
 use Wikibase\Lib\Store\PrefetchingTermLookup;
@@ -283,6 +284,11 @@
         * @var SettingsArray|null
         */
        private $clientSettings = null;
+
+       /**
+        * @var EntityRdfBuilderFactory|null
+        */
+       private $entityRdfBuilderFactory = null;
 
        /**
         * IMPORTANT: Use only when it is not feasible to inject an instance 
properly.
@@ -1868,4 +1874,17 @@
                return 
$this->entityTypeDefinitions->getChangeOpDeserializerCallbacks();
        }
 
+       /**
+        * @return EntityRdfBuilderFactory
+        */
+       public function getEntityRdfBuilderFactory() {
+               if ( $this->entityRdfBuilderFactory === null ) {
+                       $this->entityRdfBuilderFactory = new 
EntityRdfBuilderFactory(
+                               
$this->dataTypeDefinitions->getRdfBuilderFactoryCallbacks()
+                       );
+               }
+
+               return $this->entityRdfBuilderFactory;
+       }
+
 }
diff --git 
a/repo/tests/phpunit/includes/Rdf/DispatchingEntityRdfBuilderTest.php 
b/repo/tests/phpunit/includes/Rdf/DispatchingEntityRdfBuilderTest.php
new file mode 100644
index 0000000..428d90a
--- /dev/null
+++ b/repo/tests/phpunit/includes/Rdf/DispatchingEntityRdfBuilderTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Wikibase\Repo\Tests\Rdf;
+
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\ItemId;
+use Wikibase\Rdf\DispatchingEntityRdfBuilder;
+use Wikibase\Rdf\EntityRdfBuilder;
+
+/**
+ * @covers Wikibase\Rdf\DispatchingEntityRdfBuilder
+ *
+ * @group Wikibase
+ * @group WikibaseRdf
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani <ladsgr...@gmail.com>
+ */
+class DispatchingEntityRdfBuilderTest extends \PHPUnit_Framework_TestCase {
+
+       public function testAddValue() {
+               $entity = new Item( new ItemId( 'Q1' ) );
+
+               $fooBuilder = $this->getMock( EntityRdfBuilder::class );
+               $fooBuilder->expects( $this->once() )
+                       ->method( 'addEntity' )
+                       ->with( $entity );
+
+               $dispatchingBuilder = new DispatchingEntityRdfBuilder( [
+                       'item' => $fooBuilder,
+               ] );
+
+               $dispatchingBuilder->addEntity( $entity );
+       }
+
+}
diff --git a/repo/tests/phpunit/includes/Rdf/EntityRdfBuilderFactoryTest.php 
b/repo/tests/phpunit/includes/Rdf/EntityRdfBuilderFactoryTest.php
new file mode 100644
index 0000000..8a7bf59
--- /dev/null
+++ b/repo/tests/phpunit/includes/Rdf/EntityRdfBuilderFactoryTest.php
@@ -0,0 +1,103 @@
+<?php
+
+namespace Wikibase\Repo\Tests\Rdf;
+
+use Closure;
+use PHPUnit_Framework_TestCase;
+use Wikibase\Rdf\RdfProducer;
+use Wikibase\Rdf\EntityRdfBuilder;
+use Wikibase\Rdf\EntityRdfBuilderFactory;
+use Wikibase\Rdf\RdfVocabulary;
+use Wikibase\Rdf\NullEntityMentionListener;
+use Wikibase\Rdf\NullDedupeBag;
+use Wikimedia\Purtle\NTriplesRdfWriter;
+use Wikimedia\Purtle\RdfWriter;
+use Wikibase\Rdf\EntityMentionListener;
+use Wikibase\Rdf\DedupeBag;
+
+/**
+ * @covers Wikibase\Rdf\EntityRdfBuilderFactory
+ *
+ * @group Wikibase
+ * @group WikibaseRdf
+ *
+ * @license GPL-2.0+
+ * @author Amir Sarabadani <ladsgr...@gmail.com>
+ */
+class EntityRdfBuilderFactoryTest extends PHPUnit_Framework_TestCase {
+
+       public function getBuilderFlags() {
+               return [
+                       [ 0 ], // simple values
+                       [ RdfProducer::PRODUCE_FULL_VALUES ], // complex values
+               ];
+       }
+
+       /**
+        * @dataProvider getBuilderFlags
+        */
+       public function testGetEntityRdfBuilder( $flags ) {
+               $vocab = new RdfVocabulary( RdfBuilderTestData::URI_BASE, 
RdfBuilderTestData::URI_DATA );
+               $writer = new NTriplesRdfWriter();
+               $tracker = new NullEntityMentionListener();
+               $dedupe = new NullDedupeBag();
+               $called = false;
+
+               $constructor = $this->newRdfBuilderConstructorCallback(
+                       $flags, $vocab, $writer, $tracker, $dedupe, $called
+               );
+
+               $factory = new EntityRdfBuilderFactory( [ 'test' => 
$constructor ] );
+               $factory->getEntityRdfBuilder( $flags, $vocab, $writer, 
$tracker, $dedupe );
+               $this->assertTrue( $called );
+       }
+
+       /**
+        * Constructs a closure that asserts that it is being called with the 
expected parameters.
+        *
+        * @param int $expectedMode
+        * @param RdfVocabulary $expectedVocab
+        * @param RdfWriter $expectedWriter
+        * @param EntityMentionListener $expectedTracker
+        * @param DedupeBag $expectedDedupe
+        * @param bool &$called Will be set to true once the returned function 
has been called.
+        *
+        * @return Closure
+        */
+       private function newRdfBuilderConstructorCallback(
+               $expectedMode,
+               RdfVocabulary $expectedVocab,
+               RdfWriter $expectedWriter,
+               EntityMentionListener $expectedTracker,
+               DedupeBag $expectedDedupe,
+               &$called
+       ) {
+               $entityRdfBuilder = $this->getMock( EntityRdfBuilder::class );
+
+               return function(
+                       $mode,
+                       RdfVocabulary $vocab,
+                       RdfWriter $writer,
+                       EntityMentionListener $tracker,
+                       DedupeBag $dedupe
+               ) use (
+                       $expectedMode,
+                       $expectedVocab,
+                       $expectedWriter,
+                       $expectedTracker,
+                       $expectedDedupe,
+                       $entityRdfBuilder,
+                       &$called
+               ) {
+                       $this->assertSame( $expectedMode, $mode );
+                       $this->assertSame( $expectedVocab, $vocab );
+                       $this->assertSame( $expectedWriter, $writer );
+                       $this->assertSame( $expectedTracker, $tracker );
+                       $this->assertSame( $expectedDedupe, $dedupe );
+                       $called = true;
+
+                       return $entityRdfBuilder;
+               };
+       }
+
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/340696
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id5920889655136cf06800ca92d06edda4551813e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Ladsgroup <ladsgr...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to