-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clean up entity patching code #196
Changes from all commits
d7bbdf4
29cc462
c5f2f19
1a22290
198508f
fa0bfdc
ca11632
54afa34
5983453
a7251ff
45529e1
da3a009
5a3cc3c
48de4da
12de0d9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
namespace Wikibase\DataModel\Entity\Diff; | ||
|
||
use InvalidArgumentException; | ||
use RuntimeException; | ||
use Wikibase\DataModel\Entity\EntityDocument; | ||
|
||
/** | ||
* @since 1.1 | ||
* | ||
* @licence GNU GPL v2+ | ||
* @author Jeroen De Dauw < jeroendedauw@gmail.com > | ||
* @author Christoph Fischer < christoph.fischer@wikimedia.de > | ||
*/ | ||
class EntityPatcher { | ||
|
||
/** | ||
* @var EntityPatcherStrategy[] | ||
*/ | ||
private $patcherStrategies; | ||
|
||
public function __construct() { | ||
$this->registerEntityPatcherStrategy( new ItemPatcher() ); | ||
$this->registerEntityPatcherStrategy( new PropertyPatcher() ); | ||
} | ||
|
||
public function registerEntityPatcherStrategy( EntityPatcherStrategy $patcherStrategy ) { | ||
$this->patcherStrategies[] = $patcherStrategy; | ||
} | ||
|
||
/** | ||
* @param EntityDocument $entity | ||
* @param EntityDiff $patch | ||
* | ||
* @throws InvalidArgumentException | ||
* @throws RuntimeException | ||
*/ | ||
public function patchEntity( EntityDocument $entity, EntityDiff $patch ) { | ||
$this->getPatcherStrategy( $entity->getType() )->patchEntity( $entity, $patch ); | ||
} | ||
|
||
private function getPatcherStrategy( $entityType ) { | ||
foreach ( $this->patcherStrategies as $patcherStrategy ) { | ||
if ( $patcherStrategy->canPatchEntityType( $entityType ) ) { | ||
return $patcherStrategy; | ||
} | ||
} | ||
|
||
throw new RuntimeException( 'Patching the provided types of entities is not supported' ); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<?php | ||
|
||
namespace Wikibase\DataModel\Entity\Diff; | ||
|
||
use InvalidArgumentException; | ||
use Wikibase\DataModel\Entity\EntityDocument; | ||
|
||
/** | ||
* @since 1.1 | ||
* | ||
* @licence GNU GPL v2+ | ||
* @author Jeroen De Dauw < jeroendedauw@gmail.com > | ||
*/ | ||
interface EntityPatcherStrategy { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the benefit of this interface. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason we have this interface is so that we can have |
||
|
||
/** | ||
* @param string $entityType | ||
* | ||
* @return boolean | ||
*/ | ||
public function canPatchEntityType( $entityType ); | ||
|
||
/** | ||
* @param EntityDocument $entity | ||
* @param EntityDiff $patch | ||
* | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function patchEntity( EntityDocument $entity, EntityDiff $patch ); | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
namespace Wikibase\DataModel\Entity\Diff; | ||
|
||
use Diff\DiffOp\Diff\Diff; | ||
use Diff\Patcher\MapPatcher; | ||
use InvalidArgumentException; | ||
use Wikibase\DataModel\Term\AliasGroup; | ||
use Wikibase\DataModel\Term\AliasGroupList; | ||
use Wikibase\DataModel\Term\Fingerprint; | ||
use Wikibase\DataModel\Term\TermList; | ||
|
||
/** | ||
* Package private. | ||
* | ||
* @licence GNU GPL v2+ | ||
* @author Jeroen De Dauw < jeroendedauw@gmail.com > | ||
*/ | ||
class FingerprintPatcher { | ||
|
||
/** | ||
* @var MapPatcher | ||
*/ | ||
private $patcher; | ||
|
||
public function __construct() { | ||
$this->patcher = new MapPatcher(); | ||
} | ||
|
||
/** | ||
* @param Fingerprint $fingerprint | ||
* @param EntityDiff $patch | ||
* | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function patchFingerprint( Fingerprint $fingerprint, EntityDiff $patch ) { | ||
$labels = $this->patcher->patch( | ||
$fingerprint->getLabels()->toTextArray(), | ||
$patch->getLabelsDiff() | ||
); | ||
|
||
$fingerprint->setLabels( $this->newTermListFromArray( $labels ) ); | ||
|
||
$descriptions = $this->patcher->patch( | ||
$fingerprint->getDescriptions()->toTextArray(), | ||
$patch->getDescriptionsDiff() | ||
); | ||
|
||
$fingerprint->setDescriptions( $this->newTermListFromArray( $descriptions ) ); | ||
|
||
$this->patchAliases( $fingerprint, $patch->getAliasesDiff() ); | ||
} | ||
|
||
private function newTermListFromArray( $termArray ) { | ||
$termList = new TermList(); | ||
|
||
foreach ( $termArray as $language => $labelText ) { | ||
$termList->setTextForLanguage( $language, $labelText ); | ||
} | ||
|
||
return $termList; | ||
} | ||
|
||
private function patchAliases( Fingerprint $fingerprint, Diff $aliasesDiff ) { | ||
$patchedAliases = $this->patcher->patch( | ||
$this->getAliasesArrayForPatching( $fingerprint->getAliasGroups() ), | ||
$aliasesDiff | ||
); | ||
|
||
$fingerprint->setAliasGroups( $this->getAliasesFromArrayForPatching( $patchedAliases ) ); | ||
} | ||
|
||
private function getAliasesArrayForPatching( AliasGroupList $aliases ) { | ||
$textLists = array(); | ||
|
||
/** | ||
* @var AliasGroup $aliasGroup | ||
*/ | ||
foreach ( $aliases as $languageCode => $aliasGroup ) { | ||
$textLists[$languageCode] = $aliasGroup->getAliases(); | ||
} | ||
|
||
return $textLists; | ||
} | ||
|
||
private function getAliasesFromArrayForPatching( array $patchedAliases ) { | ||
$aliases = new AliasGroupList(); | ||
|
||
foreach( $patchedAliases as $languageCode => $aliasList ) { | ||
$aliases->setAliasesForLanguage( $languageCode, $aliasList ); | ||
} | ||
|
||
return $aliases; | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<?php | ||
|
||
namespace Wikibase\DataModel\Entity\Diff; | ||
|
||
use InvalidArgumentException; | ||
use Wikibase\DataModel\Entity\EntityDocument; | ||
use Wikibase\DataModel\Entity\Item; | ||
use Wikibase\DataModel\Statement\StatementListPatcher; | ||
|
||
/** | ||
* @since 1.1 | ||
* | ||
* @licence GNU GPL v2+ | ||
* @author Jeroen De Dauw < jeroendedauw@gmail.com > | ||
*/ | ||
class ItemPatcher implements EntityPatcherStrategy { | ||
|
||
/** | ||
* @var FingerprintPatcher | ||
*/ | ||
private $fingerprintPatcher; | ||
|
||
/** | ||
* @var StatementListPatcher | ||
*/ | ||
private $statementListPatcher; | ||
|
||
/** | ||
* @var SiteLinkListPatcher | ||
*/ | ||
private $siteLinkListPatcher; | ||
|
||
public function __construct() { | ||
$this->fingerprintPatcher = new FingerprintPatcher(); | ||
$this->statementListPatcher = new StatementListPatcher(); | ||
$this->siteLinkListPatcher = new SiteLinkListPatcher(); | ||
} | ||
|
||
/** | ||
* @param string $entityType | ||
* | ||
* @return boolean | ||
*/ | ||
public function canPatchEntityType( $entityType ) { | ||
return $entityType === 'item'; | ||
} | ||
|
||
/** | ||
* @param EntityDocument $entity | ||
* @param EntityDiff $patch | ||
* | ||
* @return Item | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function patchEntity( EntityDocument $entity, EntityDiff $patch ) { | ||
$this->assertIsItem( $entity ); | ||
|
||
$this->patchItem( $entity, $patch ); | ||
} | ||
|
||
private function assertIsItem( EntityDocument $item ) { | ||
if ( !( $item instanceof Item ) ) { | ||
throw new InvalidArgumentException( 'All entities need to be items' ); | ||
} | ||
} | ||
|
||
private function patchItem( Item $item, EntityDiff $patch ) { | ||
$this->fingerprintPatcher->patchFingerprint( $item->getFingerprint(), $patch ); | ||
|
||
if ( $patch instanceof ItemDiff ) { | ||
$item->setSiteLinkList( $this->siteLinkListPatcher->getPatchedSiteLinkList( | ||
$item->getSiteLinkList(), | ||
$patch->getSiteLinkDiff() | ||
) ); | ||
} | ||
|
||
$item->setStatements( $this->statementListPatcher->getPatchedStatementList( | ||
$item->getStatements(), | ||
$patch->getClaimsDiff() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a problem of this patch but we have to remember that this isn't very sane. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should also not know about fingerprints. And the "claims" in the names here should be changed to "statements". That's an |
||
) ); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?php | ||
|
||
namespace Wikibase\DataModel\Entity\Diff; | ||
|
||
use InvalidArgumentException; | ||
use Wikibase\DataModel\Entity\EntityDocument; | ||
use Wikibase\DataModel\Entity\Property; | ||
|
||
/** | ||
* @since 1.1 | ||
* | ||
* @licence GNU GPL v2+ | ||
* @author Jeroen De Dauw < jeroendedauw@gmail.com > | ||
*/ | ||
class PropertyPatcher implements EntityPatcherStrategy { | ||
|
||
/** | ||
* @var FingerprintPatcher | ||
*/ | ||
private $fingerprintPatcher; | ||
|
||
public function __construct() { | ||
$this->fingerprintPatcher = new FingerprintPatcher(); | ||
} | ||
|
||
/** | ||
* @param string $entityType | ||
* | ||
* @return boolean | ||
*/ | ||
public function canPatchEntityType( $entityType ) { | ||
return $entityType === 'property'; | ||
} | ||
|
||
/** | ||
* @param EntityDocument $entity | ||
* @param EntityDiff $patch | ||
* | ||
* @return Property | ||
* @throws InvalidArgumentException | ||
*/ | ||
public function patchEntity( EntityDocument $entity, EntityDiff $patch ) { | ||
$this->assertIsProperty( $entity ); | ||
|
||
$this->patchProperty( $entity, $patch ); | ||
} | ||
|
||
private function assertIsProperty( EntityDocument $property ) { | ||
if ( !( $property instanceof Property ) ) { | ||
throw new InvalidArgumentException( 'All entities need to be properties' ); | ||
} | ||
} | ||
|
||
private function patchProperty( Property $property, EntityDiff $patch ) { | ||
$this->fingerprintPatcher->patchFingerprint( $property->getFingerprint(), $patch ); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot see why we need this class. Per below we shouldn't have an
EntityPatcherStrategy
interface and then we also won't need and cannot have anEntityPatcher
.