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