Bene has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/271236

Change subject: [WIP] Register EntityFactory via callbacks
......................................................................

[WIP] Register EntityFactory via callbacks

Change-Id: I56827a4e9199dfaa19218553f91c50d9199ebef2
---
M client/includes/WikibaseClient.php
M lib/WikibaseLib.entitytypes.php
M lib/includes/EntityFactory.php
M lib/includes/EntityTypeDefinitions.php
M lib/tests/phpunit/entity/EntityFactoryTest.php
M repo/includes/WikibaseRepo.php
6 files changed, 57 insertions(+), 50 deletions(-)


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

diff --git a/client/includes/WikibaseClient.php 
b/client/includes/WikibaseClient.php
index f820f50..c8e8c36 100644
--- a/client/includes/WikibaseClient.php
+++ b/client/includes/WikibaseClient.php
@@ -772,14 +772,7 @@
         * @return EntityFactory
         */
        public function getEntityFactory() {
-               $entityClasses = array(
-                       Item::ENTITY_TYPE => 'Wikibase\DataModel\Entity\Item',
-                       Property::ENTITY_TYPE => 
'Wikibase\DataModel\Entity\Property',
-               );
-
-               //TODO: provide a hook or registry for adding more.
-
-               return new EntityFactory( $entityClasses );
+               return new EntityFactory( 
$this->entityTypeDefinitions->getEntityFactoryCallbacks() );
        }
 
        /**
diff --git a/lib/WikibaseLib.entitytypes.php b/lib/WikibaseLib.entitytypes.php
index 7804d86..d88c994 100644
--- a/lib/WikibaseLib.entitytypes.php
+++ b/lib/WikibaseLib.entitytypes.php
@@ -16,6 +16,8 @@
  */
 
 use Wikibase\DataModel\DeserializerFactory;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\Property;
 use Wikibase\DataModel\SerializerFactory;
 use Wikibase\EntityChange;
 use Wikibase\ItemChange;
@@ -28,6 +30,9 @@
                'deserializer-factory-callback' => function( 
DeserializerFactory $deserializerFactory ) {
                        return $deserializerFactory->newItemDeserializer();
                },
+               'entity-factory-callback' => function() {
+                       return new Item();
+               },
                'change-factory-callback' => function( array $fields ) {
                        return new ItemChange( $fields );
                }
@@ -39,6 +44,9 @@
                'deserializer-factory-callback' => function( 
DeserializerFactory $deserializerFactory ) {
                        return $deserializerFactory->newPropertyDeserializer();
                },
+               'entity-factory-callback' => function() {
+                       return Property::newFromType( '' );
+               },
                'change-factory-callback' => function( array $fields ) {
                        return new EntityChange( $fields );
                }
diff --git a/lib/includes/EntityFactory.php b/lib/includes/EntityFactory.php
index bba224c..21c16c5 100644
--- a/lib/includes/EntityFactory.php
+++ b/lib/includes/EntityFactory.php
@@ -2,9 +2,11 @@
 
 namespace Wikibase;
 
+use InvalidArgumentException;
 use OutOfBoundsException;
 use RuntimeException;
 use Wikibase\DataModel\Entity\EntityDocument;
+use Wikimedia\Assert\Assert;
 
 /**
  * Factory for Entity objects.
@@ -22,17 +24,20 @@
 class EntityFactory {
 
        /**
-        * @var array Maps entity types to classes implementing the respective 
entity.
+        * @var callable[] Maps entity types to callbacks to create an instance 
the respective entity.
         */
-       private $typeMap;
+       private $callbacks;
 
        /**
         * @since 0.5
         *
-        * @param array $typeToClass Maps entity types to classes implementing 
the respective entity.
+        * @param callable[] $callbacks Maps entity types to callbacks to 
create an instance the respective entity.
+        * @throws InvalidArgumentException
         */
-       public function __construct( array $typeToClass ) {
-               $this->typeMap = $typeToClass;
+       public function __construct( array $callbacks ) {
+               Assert::parameterElementType( 'callable', $callbacks, 
'$callbacks' );
+
+               $this->callbacks = $callbacks;
        }
 
        /**
@@ -43,7 +48,7 @@
         * @return array all available type identifiers
         */
        public function getEntityTypes() {
-               return array_keys( $this->typeMap );
+               return array_keys( $this->callbacks );
        }
 
        /**
@@ -56,23 +61,7 @@
         * @return bool
         */
        public function isEntityType( $type ) {
-               return array_key_exists( $type, $this->typeMap );
-       }
-
-       /**
-        * Returns the class implementing the given entity type.
-        *
-        * @param string $type
-        *
-        * @throws OutOfBoundsException
-        * @return string Class
-        */
-       private function getEntityClass( $type ) {
-               if ( !isset( $this->typeMap[$type] ) ) {
-                       throw new OutOfBoundsException( 'Unknown entity type ' 
. $type );
-               }
-
-               return $this->typeMap[$type];
+               return array_key_exists( $type, $this->callbacks );
        }
 
        /**
@@ -82,19 +71,22 @@
         *
         * @param String $entityType The type of the desired new entity.
         *
-        * @throws RuntimeException
+        * @throws OutOfBoundsException
         * @return EntityDocument The new Entity object.
         */
        public function newEmpty( $entityType ) {
-               $class = $this->getEntityClass( $entityType );
-
-               if ( method_exists( $class, 'newFromType' ) ) {
-                       return $class::newFromType( '' );
-               } elseif ( method_exists( $class, 'newEmpty' ) ) {
-                       return $class::newEmpty();
-               } else {
-                       throw new RuntimeException( "$class does not support a 
newEmpty method" );
+               if ( !isset( $this->callbacks[$entityType] ) ) {
+                       throw new OutOfBoundsException( 'Unknown entity type ' 
. $entityType );
                }
+
+               $entity = call_user_func( $this->callbacks[$entityType] );
+
+               Assert::postcondition(
+                       $entity instanceof EntityDocument && $entity->getType() 
=== $entityType,
+                       'Callback returned no entity or entity of wrong type'
+               );
+
+               return $entity;
        }
 
 }
diff --git a/lib/includes/EntityTypeDefinitions.php 
b/lib/includes/EntityTypeDefinitions.php
index 49f28cd..5d24135 100644
--- a/lib/includes/EntityTypeDefinitions.php
+++ b/lib/includes/EntityTypeDefinitions.php
@@ -54,6 +54,13 @@
        /**
         * @return callable[]
         */
+       public function getEntityFactoryCallbacks() {
+               return $this->entityTypeDefinitions->getMapForDefinitionField( 
'entity-factory-callback' );
+       }
+
+       /**
+        * @return callable[]
+        */
        public function getChangeFactoryCallbacks() {
                return $this->entityTypeDefinitions->getMapForDefinitionField( 
'change-factory-callback' );
        }
diff --git a/lib/tests/phpunit/entity/EntityFactoryTest.php 
b/lib/tests/phpunit/entity/EntityFactoryTest.php
index c7b5aab..09ad47b 100644
--- a/lib/tests/phpunit/entity/EntityFactoryTest.php
+++ b/lib/tests/phpunit/entity/EntityFactoryTest.php
@@ -2,6 +2,9 @@
 
 namespace Wikibase\Test;
 
+use InvalidArgumentException;
+use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Entity\Property;
 use Wikibase\EntityFactory;
 
 /**
@@ -16,10 +19,21 @@
  */
 class EntityFactoryTest extends \MediaWikiTestCase {
 
+       /**
+        * @expectedException InvalidArgumentException
+        */
+       public function 
testConstructorWithNoCallback_throwsInvalidArgumentException() {
+               new EntityFactory( array( 'foo' => 'bar' ) );
+       }
+
        private function getEntityFactory() {
                return new EntityFactory( array(
-                       'item' => 'Wikibase\DataModel\Entity\Item',
-                       'property' => 'Wikibase\DataModel\Entity\Property',
+                       'item' => function() {
+                               return new Item();
+                       },
+                       'property' => function() {
+                               return Property::newFromType( '' );
+                       }
                ) );
        }
 
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index 8afe259..0027d63 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -1118,14 +1118,7 @@
         * @return EntityFactory
         */
        public function getEntityFactory() {
-               $entityClasses = array(
-                       Item::ENTITY_TYPE => 'Wikibase\DataModel\Entity\Item',
-                       Property::ENTITY_TYPE => 
'Wikibase\DataModel\Entity\Property',
-               );
-
-               //TODO: provide a hook or registry for adding more.
-
-               return new EntityFactory( $entityClasses );
+               return new EntityFactory( 
$this->entityTypeDefinitions->getEntityFactoryCallbacks() );
        }
 
        /**

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I56827a4e9199dfaa19218553f91c50d9199ebef2
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Bene <benestar.wikime...@gmail.com>

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

Reply via email to