Daniel Werner has submitted this change and it was merged.

Change subject: Refactor RDF mapping, added support for sitelinks.
......................................................................


Refactor RDF mapping, added support for sitelinks.

Change-Id: Ibf1499d1f0742db7fbeb5cb3180552fc59cddb2d
---
M lib/includes/formatters/EntityIdFormatter.php
M repo/Wikibase.classes.php
M repo/Wikibase.hooks.php
M repo/includes/WikibaseRepo.php
A repo/includes/content/RdfBuilder.php
M repo/includes/content/RdfSerializer.php
M repo/includes/specials/SpecialEntityData.php
A repo/tests/phpunit/includes/content/RdfBuilderTest.php
M repo/tests/phpunit/includes/content/RdfSerializerTest.php
9 files changed, 882 insertions(+), 262 deletions(-)

Approvals:
  Daniel Werner: Verified; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/lib/includes/formatters/EntityIdFormatter.php 
b/lib/includes/formatters/EntityIdFormatter.php
index 0fa8b7a..61d0304 100644
--- a/lib/includes/formatters/EntityIdFormatter.php
+++ b/lib/includes/formatters/EntityIdFormatter.php
@@ -69,9 +69,9 @@
         *
         * @since 0.4
         *
-        * @param mixed $value The value to format
+        * @param EntityId $value The ID to format
         *
-        * @return Result
+        * @return string
         * @throws InvalidArgumentException
         * @throws OutOfBoundsException
         */
diff --git a/repo/Wikibase.classes.php b/repo/Wikibase.classes.php
index 3b8136c..4982b70 100644
--- a/repo/Wikibase.classes.php
+++ b/repo/Wikibase.classes.php
@@ -96,6 +96,7 @@
                'Wikibase\ItemHandler' => 'includes/content/ItemHandler.php',
                'Wikibase\PropertyContent' => 
'includes/content/PropertyContent.php',
                'Wikibase\PropertyHandler' => 
'includes/content/PropertyHandler.php',
+               'Wikibase\RdfBuilder' => 'includes/content/RdfBuilder.php',
                'Wikibase\RdfSerializer' => 
'includes/content/RdfSerializer.php',
 
                // EasyRdf
@@ -167,6 +168,7 @@
                'Wikibase\Test\Api\LangAttributeBase' => 
'tests/phpunit/includes/api/LangAttributeBase.php',
                'Wikibase\Test\EntityContentTest' => 
'tests/phpunit/includes/content/EntityContentTest.php',
                'Wikibase\Test\EntityHandlerTest' => 
'tests/phpunit/includes/content/EntityHandlerTest.php',
+               'Wikibase\Test\RdfBuilderTest' => 
'tests/phpunit/includes/content/RdfBuilderTest.php',
 
                'MessageReporter' => 'includes/MessageReporter.php',
                'ObservableMessageReporter' => 'includes/MessageReporter.php',
diff --git a/repo/Wikibase.hooks.php b/repo/Wikibase.hooks.php
index 16501ab..6905fb0 100755
--- a/repo/Wikibase.hooks.php
+++ b/repo/Wikibase.hooks.php
@@ -190,6 +190,8 @@
                        'content/ItemHandler',
                        'content/PropertyContent',
                        'content/PropertyHandler',
+                       'content/RdfBuilder',
+                       'content/RdfSerializer',
 
                        'specials/SpecialNewItem',
                        'specials/SpecialNewProperty',
diff --git a/repo/includes/WikibaseRepo.php b/repo/includes/WikibaseRepo.php
index da21dc7..d63ec1b 100644
--- a/repo/includes/WikibaseRepo.php
+++ b/repo/includes/WikibaseRepo.php
@@ -3,6 +3,7 @@
 namespace Wikibase\Repo;
 
 use DataTypes\DataTypeFactory;
+use ValueFormatters\FormatterOptions;
 use ValueParsers\ParserOptions;
 use Wikibase\Lib\EntityIdFormatter;
 use Wikibase\Lib\EntityIdLabelFormatter;
@@ -47,6 +48,11 @@
        private $dataTypeFactory = null;
 
        /**
+        * @var EntityIdFormatter|null
+        */
+       private $idFormatter = null;
+
+       /**
         * @since 0.4
         *
         * @param SettingsArray $settings
@@ -76,6 +82,29 @@
        }
 
        /**
+        * @since 0.4
+        *
+        * @return EntityIdFormatter
+        */
+       public function getIdFormatter() {
+               if ( $this->idFormatter === null ) {
+                       $prefixMap = array();
+
+                       foreach ( $this->settings->getSetting( 'entityPrefixes' 
) as $prefix => $entityType ) {
+                               $prefixMap[$entityType] = $prefix;
+                       }
+
+                       $options = new FormatterOptions( array(
+                               EntityIdFormatter::OPT_PREFIX_MAP => $prefixMap
+                       ) );
+
+                       $this->idFormatter = new EntityIdFormatter( $options );
+               }
+
+               return $this->idFormatter;
+       }
+
+       /**
         * Returns the base to use when generating URIs for use in RDF output.
         *
         * @return string
diff --git a/repo/includes/content/RdfBuilder.php 
b/repo/includes/content/RdfBuilder.php
new file mode 100755
index 0000000..60df0dd
--- /dev/null
+++ b/repo/includes/content/RdfBuilder.php
@@ -0,0 +1,485 @@
+<?php
+
+namespace Wikibase;
+
+/**
+ * RDF mapping for wikibase data model.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 0.4
+ *
+ * @file
+ * @ingroup WikibaseRepo
+ * @ingroup Content
+ * @ingroup RDF
+ *
+ * @licence GNU GPL v2+
+ * @author Anja Jentzsch < [email protected] >
+ * @author Thomas Pellissier Tanon
+ * @author Daniel Kinzler
+ */
+
+use DataTypes\DataTypeFactory;
+use DataValues\DataValue;
+use EasyRdf_Format;
+use EasyRdf_Graph;
+use EasyRdf_Namespace;
+use EasyRdf_Resource;
+use Revision;
+use Wikibase\Lib\EntityIdFormatter;
+
+class RdfBuilder {
+
+       const ONTOLOGY_BASE_URI = 'http://www.wikidata.org/ontology#'; //XXX: 
Denny made me put the "www" there...
+
+       const NS_ONTOLOGY =  'wikibase'; // wikibase ontology (shared)
+       const NS_ENTITY =    'entity';   // concept uris
+       const NS_DATA =      'data';     // document uris
+       const NS_PROPERTY =  'p'; // entity -> value
+       const NS_VALUE =     'v'; // statement -> value
+       const NS_QUALIFIER = 'q'; // statement -> qualifier
+       const NS_STATEMENT = 's'; // entity -> statement
+
+       const NS_SKOS = 'skos'; // SKOS vocabulary
+       const NS_FOAF = 'foaf'; // FOAF vocabulary
+
+       const SKOS_URI = 'http://www.w3.org/2004/02/skos/core#';
+       const FOAF_URI = 'http://xmlns.com/foaf/0.1/';
+
+       const WIKIBASE_STATEMENT_QNAME = 'wikibase:Statement';
+
+       /**
+        * Map of qnames to namespace URIs
+        *
+        * @var array
+        */
+       protected $namespaces = array();
+
+       /**
+        * A list of entities mentioned/touched to or by this builder.
+        * The prefixed entity IDs are used as keys in the array, the values 
'true'
+        * is used to indicate that the entity has been resolved, 'false' 
indicates
+        * that the entity was mentioned but not resolved (defined).
+        *
+        * @var array
+        */
+       protected $entitiesResolved = array();
+
+       /**
+        * @param string                $baseUri
+        * @param Lib\EntityIdFormatter $idFormatter
+        * @param EasyRdf_Graph|null    $graph
+        */
+       public function __construct(
+               $baseUri,
+               EntityIdFormatter $idFormatter,
+               EasyRdf_Graph $graph = null
+       ) {
+               if ( !$graph ) {
+                       $graph = new EasyRdf_Graph();
+               }
+
+               $this->graph = $graph;
+               $this->baseUri = $baseUri;
+               $this->idFormatter = $idFormatter;
+
+               $this->namespaces = array(
+                       self::NS_ONTOLOGY => self::ONTOLOGY_BASE_URI,
+                       self::NS_DATA => $this->baseUri . '/data/',
+                       self::NS_ENTITY => $this->baseUri . '/entity/',
+                       self::NS_PROPERTY => $this->baseUri . '/property/',
+                       self::NS_VALUE => $this->baseUri . '/value/',
+                       self::NS_QUALIFIER => $this->baseUri . '/qualifier/',
+                       self::NS_STATEMENT => $this->baseUri . '/statement/',
+                       self::NS_SKOS => self::SKOS_URI,
+                       self::NS_FOAF => self::FOAF_URI,
+               );
+
+               //XXX: Ugh, static. Should go into $this->graph.
+               foreach ( $this->getNamespaces() as $gname => $uri ) {
+                       EasyRdf_Namespace::set( $gname, $uri );
+               }
+       }
+
+       /**
+        * Checks whether the necessary libraries for RDF serialization are 
installed.
+        */
+       public static function isSupported() {
+               // check that the submodule is present
+               $file = __DIR__ . '/easyRdf/EasyRdf.php';
+               return file_exists( $file ) && class_exists( 'EasyRdf_Graph' );
+       }
+
+       /**
+        * Returns the builder's graph
+        *
+        * @return EasyRdf_Graph
+        */
+       public function getGraph() {
+               return $this->graph;
+       }
+
+       /**
+        * Returns a map of namespace names to URIs
+        *
+        * @return array
+        */
+       public function getNamespaces() {
+               return $this->namespaces;
+       }
+
+       /**
+        * Returns a qname for the given entity using the given prefix.
+        * To refer to the entity as such, use self::NS_ENTITY.
+        * To refer to the description of the entity, use NS_DATA.
+        * For the different prefixes used for properties in statements,
+        * refer to the Wikibase RDF mapping spec.
+        *
+        * @param string   $prefix use a self::NS_XXX constant
+        * @param EntityId $id
+        *
+        * @return string
+        */
+       public function getEntityQName( $prefix, EntityId $id ) {
+               return $prefix . ':' . $this->idFormatter->format( $id );
+       }
+
+       /**
+        * Returns a qname for the given statement using the given prefix.
+        *
+        * @param string $prefix use a self::NS_XXX constant, usually 
self::NS_STATEMENT
+        * @param Claim $claim
+        *
+        * @return string
+        */
+       public function getStatementQName( $prefix, Claim $claim ) {
+               return $prefix . ':' . $claim->getGuid();
+       }
+
+       /**
+        * Returns a qname for the given entity type.
+        * For well known types, these qnames refer to classes from the 
Wikibase ontology.
+        *
+        * @param $type
+        *
+        * @return string
+        */
+       public function getEntityTypeQName( $type ) {
+               //TODO: the list of types is configurable, need to register 
URIs for extra types!
+
+               return self::NS_ONTOLOGY . ':' . ucfirst( $type );
+       }
+
+       /**
+        * Gets a resource object representing the given entity
+        *
+        * @param EntityId $id
+        *
+        * @return EasyRDF_Resource
+        */
+       public function getEntityResource( EntityId $id ) {
+               $entityQName = $this->getEntityQName( self::NS_ENTITY, $id );
+               $entityResource = $this->graph->resource( $entityQName );
+               return $entityResource;
+       }
+
+       /**
+        * Language filter
+        *
+        * @param $lang
+        *
+        * @return bool
+        */
+       protected function isLanguageIncluded( $lang ) {
+               return true; //todo: optional filter
+       }
+
+       /**
+        * Registers an entity as mentioned. Will be recorded as unresolved
+        * if it wasn't already marked as resolved.
+        *
+        * @param EntityId $id
+        */
+       protected function entityMentioned( EntityId $id ) {
+               $prefixedId = $this->idFormatter->format( $id );
+
+               if ( !isset( $this->entitiesResolved[$prefixedId] ) ) {
+                       $this->entitiesResolved[$prefixedId] = false;
+               }
+       }
+
+       /**
+        * Registers an entity as resolved.
+        *
+        * @param EntityId $id
+        */
+       protected function entityResolved( EntityId $id ) {
+               $prefixedId = $this->idFormatter->format( $id );
+               $this->entitiesResolved[$prefixedId] = true;
+       }
+
+       /**
+        * Adds meta-information about an entity (such as the ID and type) to 
the RDF graph.
+        *
+        * @param Entity         $entity
+        * @param \Revision|null $rev
+        */
+       public function addEntityMetaData( Entity $entity, Revision $rev = null 
) {
+               $entityResource = $this->getEntityResource( $entity->getId() );
+               $entityResource->addResource( 'rdf:type', 
$this->getEntityTypeQName( $entity->getType() ) );
+               $entityResource->addResource( 'foaf:primaryTopicOf', 
$this->getEntityQName( self::NS_DATA, $entity->getId() ) );
+
+               //TODO: revision timestamp, revision id, versioned data URI
+
+               $this->entityResolved( $entity->getId() );
+       }
+
+       /**
+        * Adds the labels of the given entity to the RDF graph
+        *
+        * @param Entity $entity
+        */
+       public function addLabels( Entity $entity ) {
+               $entityResource = $this->getEntityResource( $entity->getId() );
+
+               foreach ( $entity->getLabels() as $languageCode => $labelText ) 
{
+                       if ( !$this->isLanguageIncluded( $languageCode ) ) {
+                               continue;
+                       }
+
+                       $entityResource->addLiteral( 'rdfs:label', $labelText, 
$languageCode );
+                       $entityResource->addLiteral( 'skos:prefLabel', 
$labelText, $languageCode );
+               }
+       }
+
+       /**
+        * Adds the descriptions of the given entity to the RDF graph.
+        *
+        * @param Entity $entity
+        */
+       public function addDescriptions( Entity $entity ) {
+               $entityResource = $this->getEntityResource( $entity->getId() );
+
+               foreach ( $entity->getDescriptions() as $languageCode => 
$description ) {
+                       if ( !$this->isLanguageIncluded( $languageCode ) ) {
+                               continue;
+                       }
+
+                       $entityResource->addLiteral( 'skos:note', $description, 
$languageCode );
+               }
+       }
+
+       /**
+        * Adds the aliases of the given entity to the RDF graph.
+        *
+        * @param Entity $entity
+        */
+       public function addAliases( Entity $entity ) {
+               $entityResource = $this->getEntityResource( $entity->getId() );
+
+               foreach ( $entity->getAllAliases() as $languageCode => $aliases 
) {
+                       if ( !$this->isLanguageIncluded( $languageCode ) ) {
+                               continue;
+                       }
+
+                       foreach ( $aliases as $alias ) {
+                               $entityResource->addLiteral( 'skos:altLabel', 
$alias, $languageCode );
+                       }
+               }
+       }
+
+       /**
+        * Adds the site links of the given item to the RDF graph.
+        *
+        * @param Item $item
+        */
+       public function addSiteLinks( Item $item ) {
+               $entityResource = $this->getEntityResource( $item->getId() );
+
+               /* @var SiteLink $link */
+               foreach ( $item->getSiteLinks() as $link ) {
+                       $languageCode = $link->getSite()->getLanguageCode();
+
+                       if ( !$this->isLanguageIncluded( $languageCode ) ) {
+                               continue;
+                       }
+
+                       $pageRecourse = $this->graph->resource( $link->getUrl() 
);
+                       $entityResource->addResource( 'foaf:primaryTopicOf', 
$pageRecourse, $languageCode );
+               }
+       }
+
+       /**
+        * Adds all Claims/Statements from the given entity to the RDF graph.
+        *
+        * @param Entity $entity
+        */
+       public function addClaims( Entity $entity ) {
+               /* @var Claim $claim */
+               foreach( $entity->getClaims() as $claim ) {
+                       $this->addClaim( $entity, $claim );
+               }
+       }
+
+       /**
+        * Adds the given Claim from the given Entity to the RDF graph.
+        *
+        * @param Entity $entity
+        * @param Claim  $claim
+        */
+       public function addClaim( Entity $entity, Claim $claim ) {
+               $this->addMainSnak( $entity, $claim );
+
+               //TODO: add qualifiers
+               //TODO: add references
+       }
+
+       /**
+        * Adds the given Claim's main Snak to the RDF graph.
+        *
+        * @param Entity $entity
+        * @param Claim  $claim
+        */
+       public function addMainSnak( Entity $entity, Claim $claim ) {
+               $snak = $claim->getMainSnak();
+
+               if ( $snak instanceof PropertyValueSnak ) {
+                       $this->addPropertyValueSnak( $entity, $claim, $snak );
+               } else {
+                       //TODO: NoValueSnak, SomeValueSnak
+                       wfWarn( "Unsupported snak type: " . get_class( $snak ) 
);
+               }
+       }
+
+
+       /**
+        * Returns a resource representing the given claim.
+        *
+        * @param Claim $claim
+        *
+        * @return EasyRDF_Resource
+        */
+       public function getStatementResource( Claim $claim ) {
+               $statementQName = $this->getStatementQName( self::NS_STATEMENT, 
$claim );
+               $statementResource = $this->graph->resource( $statementQName, 
array( self::WIKIBASE_STATEMENT_QNAME ) );
+               return $statementResource;
+       }
+
+       /**
+        * Adds the given PropertyValueSnak to the RDF graph.
+        *
+        * @param Entity            $entity
+        * @param PropertyValueSnak $snak
+        * @param Claim             $claim
+        */
+       public function addPropertyValueSnak( Entity $entity, Claim $claim, 
PropertyValueSnak $snak ) {
+               $entityResource = $this->getEntityResource( $entity->getId() );
+
+               $propertyId = $claim->getMainSnak()->getPropertyId();
+               $propertyQName = $this->getEntityQName( self::NS_PROPERTY, 
$propertyId );
+
+               $statementResource = $this->getStatementResource( $claim );
+               $entityResource->addResource( $propertyQName, 
$statementResource );
+
+               $value = $snak->getDataValue()->getValue();
+
+               $this->entityMentioned( $propertyId );
+               $this->addClaimValue( $claim, $propertyId, $value );
+       }
+
+       /**
+        * Adds the value of the given property to the RDF graph.
+        *
+        * @param Claim     $claim
+        * @param EntityId  $propertyId
+        * @param DataValue $value
+        */
+       public function addClaimValue( Claim $claim, EntityId $propertyId, 
DataValue $value ) {
+               $statementResource = $this->getStatementResource( $claim );
+               $propertyValueQName = $this->getEntityQName( self::NS_VALUE, 
$propertyId );
+
+               $typeId = $value->getType();
+
+               switch ( $typeId ) {
+                       case 'wikibase-item':
+                               $rawValue = $value->getValue();
+
+                               assert( $rawValue instanceof EntityId );
+                               $valueQName = $this->getEntityQName( 
self::NS_ENTITY, $rawValue );
+                               $valueResource = $this->graph->resource( 
$valueQName );
+                               $statementResource->addResource( 
$propertyValueQName, $valueResource );
+                               $this->entityMentioned( $rawValue );
+                               break;
+                       case 'commonsMedia':
+                               $statementResource->addResource( 
$propertyValueQName, $value );
+                               break;
+                       default:
+                               //TODO: more media types
+                               wfWarn( "Unsupported data type: $typeId" );
+               }
+       }
+
+       /**
+        * Add stubs for any entities that were previously mentioned (e.g. as 
properties
+        * or data values).
+        *
+        * @param EntityLookup $entityLookup
+        */
+       public function resolvedMentionedEntities( EntityLookup $entityLookup ) 
{
+               foreach ( $this->entitiesResolved as $id => $resolved ) {
+                       if ( !$resolved ) {
+                               $id = EntityId::newFromPrefixedId( $id );
+                               $entity = $entityLookup->getEntity( $id );
+
+                               $this->addEntityStub( $entity );
+                       }
+               }
+       }
+
+       /**
+        * Add an entity to the RDF graph, including all supported structural 
components
+        * of the entity.
+        *
+        * @param Entity $entity the entity to output.
+        * @param \Revision $revision for meta data (optional)
+        */
+       public function addEntity( Entity $entity, \Revision $revision = null ) 
{
+               $this->addEntityMetaData( $entity, $revision );
+
+               $this->addLabels( $entity );
+               $this->addDescriptions( $entity );
+               $this->addAliases( $entity );
+
+               if ( $entity instanceof Item ) {
+                       $this->addSiteLinks( $entity );
+               }
+
+               $this->addClaims( $entity );
+       }
+
+       /**
+        * Adds stub information for the given Entity to the RDF graph. Stub 
information
+        * means meta information and labels.
+        *
+        * @param Entity $entity
+        */
+       public function addEntityStub( Entity $entity ) {
+               $this->addEntityMetaData( $entity );
+               $this->addLabels( $entity );
+               $this->addDescriptions( $entity );
+       }
+}
diff --git a/repo/includes/content/RdfSerializer.php 
b/repo/includes/content/RdfSerializer.php
index 01c3e36..54f5c3d 100755
--- a/repo/includes/content/RdfSerializer.php
+++ b/repo/includes/content/RdfSerializer.php
@@ -3,7 +3,7 @@
 namespace Wikibase;
 
 /**
- * RDF mapping for wikibase data model.
+ * RDF serialization for wikibase data model.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@
  * @file
  * @ingroup WikibaseRepo
  * @ingroup Content
+ * @ingroup RDF
  *
  * @licence GNU GPL v2+
  * @author Anja Jentzsch < [email protected] >
@@ -37,13 +38,13 @@
 use EasyRdf_Format;
 use EasyRdf_Graph;
 use EasyRdf_Namespace;
+use Wikibase\Lib\EntityIdFormatter;
 
 class RdfSerializer {
 
-       const ontologyBaseUri = 'http://www.wikidata.org'; //XXX: Denny made me 
put the "www" there...
-
        /**
         * @var DataTypeFactory
+        * @note: currently unused. keep?
         */
        protected $dataTypeFactory;
 
@@ -58,47 +59,31 @@
        protected $format;
 
        /**
-        * Map of gnames to namespace URIs
-        *
-        * @var array
-        */
-       protected $namespaces = array();
-
-       /**
-        * @param EasyRdf_Format  $format
-        * @param string          $uriBase
-        * @param EntityLookup    $entityLookup
-        * @param DataTypeFactory $dataTypeFactory
+        * @param EasyRdf_Format        $format
+        * @param string                $uriBase
+        * @param EntityLookup          $entityLookup
+        * @param DataTypeFactory       $dataTypeFactory
+        * @param Lib\EntityIdFormatter $idFormatter
         */
        public function __construct(
                EasyRdf_Format $format,
                $uriBase,
                EntityLookup $entityLookup,
-               DataTypeFactory $dataTypeFactory
+               DataTypeFactory $dataTypeFactory,
+               EntityIdFormatter $idFormatter
        ) {
                $this->uriBase = $uriBase;
                $this->format = $format;
                $this->entityLookup = $entityLookup;
                $this->dataTypeFactory = $dataTypeFactory;
-
-               $this->namespaces = array(
-                       'wikibase_ontology' => self::ontologyBaseUri . 
'/ontology/',
-                       'wikibase_entity' => $this->uriBase . '/entity/',
-                       'wikibase_data' => $this->uriBase . '/data/',
-                       'wikibase_property' => $this->uriBase . '/property/',
-                       'wikibase_value' => $this->uriBase . '/value/',
-                       'wikibase_qualifier' => $this->uriBase . '/qualifier/',
-                       'wikibase_statement' => $this->uriBase . '/statement/',
-               );
+               $this->idFormatter = $idFormatter;
        }
 
        /**
         * Checks whether the necessary libraries for RDF serialization are 
installed.
         */
        public static function isSupported() {
-               // check that the submodule is present
-               $file = __DIR__ . '/easyRdf/EasyRdf.php';
-               return file_exists( $file ) && class_exists( 'EasyRdf_Graph' );
+               return RdfBuilder::isSupported();
        }
 
        /**
@@ -109,7 +94,7 @@
         * If no format is found for $name, or EasyRdf is not installed,
         * this method returns null.
         *
-        * @param $name the name (file extension, mime type) of the desired 
format.
+        * @param string $name the name (file extension, mime type) of the 
desired format.
         *
         * @return EasyRdf_Format|null the format object, or null if not found.
         */
@@ -130,26 +115,27 @@
        }
 
        public function getNamespaces() {
-               return $this->namespaces;
+               return $this->newRdfBuilder()->getNamespaces(); //XXX: nasty 
hack!
        }
 
        /**
-        * Inits a new Graph
+        * Creates a new builder
         *
-        * @return EasyRdf_Graph
+        * @return RdfBuilder
         */
-       protected function newRdfGraph() {
-               //register namespaces (ugh, static crap)
+       public function newRdfBuilder() {
+               //TODO: language filter
 
-               foreach ( $this->getNamespaces() as $gname => $uri ) {
-                       EasyRdf_Namespace::set( $gname, $uri );
-               }
+               $builder = new RdfBuilder(
+                       $this->uriBase,
+                       $this->idFormatter
+               );
 
-               return new EasyRdf_Graph();
+               return $builder;
        }
 
        /**
-        * Add an entity to the RDF graph
+        * Generates an RDF graph representing the given entity
         *
         * @param Entity $entity the entity to output.
         * @param \Revision $revision for meta data (optional)
@@ -157,82 +143,12 @@
         * @return EasyRdf_Graph
         */
        public function buildGraphForEntity( Entity $entity, \Revision 
$revision = null ) {
-               $graph = $this->newRdfGraph();
+               $builder = $this->newRdfBuilder();
 
-               $entityUri = 'wikibase_id:' . ucfirst( 
$entity->getId()->getPrefixedId() );
-               $entityResource = $graph->resource( $entityUri );
+               $builder->addEntity( $entity, $revision );
+               $builder->resolvedMentionedEntities( $this->entityLookup ); 
//TODO: optional
 
-               //TODO: filter language
-
-               foreach ( $entity->getLabels() as $languageCode => $labelText ) 
{
-                       //TODO: also skos:prefLabel
-                       $entityResource->addLiteral( 'rdfs:label', $labelText, 
$languageCode );
-               }
-
-               foreach ( $entity->getDescriptions() as $languageCode => 
$description ) {
-                       //TODO: use skos:note
-                       $entityResource->addLiteral( 'rdfs:comment', 
$description, $languageCode );
-               }
-
-               foreach ( $entity->getAllAliases() as $languageCode => $aliases 
) {
-                       foreach ( $aliases as $alias ) {
-                               //TODO: use skos:altLabel
-                               $entityResource->addLiteral( 
'wikibase_ontology:knownAs', $alias, $languageCode );
-                       }
-               }
-
-               $claims = $entity->getClaims();
-               $claimsByProperty = array();
-               foreach( $claims as $claim ) {
-                       $propertyId = $claim->getMainSnak()->getPropertyId();
-                       $claimsByProperty[$propertyId->getNumericId()][] = 
$claim;
-               }
-
-               //TODO: (optionally?) find referenced entities (items and 
properties)
-               //      and include basic info about them
-
-               /* @var Claim[] $claims */
-               foreach( $claimsByProperty as $claims ) {
-                       $counter = 1;
-                       $propertyId = 
$claims[0]->getMainSnak()->getPropertyId();
-                       $propertyUri = 'wikibase_property:' . strval( 
$propertyId );
-
-                       /* @var Property $property */
-                       $property = $this->entityLookup->getEntity( $propertyId 
);
-
-                       //$property->getEntity()->getLabel( $languageCode );
-                       $valueUri = 'wikibase_value:' . strval( $propertyId );
-
-                       foreach( $claims as $claim ) {
-                               $snak = $claim->getMainSnak();
-                               if ( $snak instanceof PropertyValueSnak ) {
-                                       $value = 
$claim->getMainSnak()->getDataValue()->getValue();
-
-                                       $statementUri = 'wikibase_statement:' . 
ucfirst( $claim->getGuid() );
-                                       $statementResource = $graph->resource( 
$statementUri, array( 'wikibase_ontology:Statement' ) );
-
-                                       $entityResource->addResource( 
$propertyUri, $statementResource );
-                                       if ( $property->getType() == 
$this->dataTypeFactory->getType( 'wikibase-item' ) ) {
-                                               $value = 'wikibase_id:' . 
ucfirst( $value );
-                                               
$statementResource->addResource( $valueUri, $value );
-                                       }
-                                       if ( $property->getType() == 
$this->dataTypeFactory->getType( 'commonsMedia' ) ) {
-                                               
$statementResource->addResource( $valueUri, $value );
-                                       }
-
-                                       //TODO: sane mechanism for extending 
this? Some kind of expert logic?
-
-                                       $counter += 1;
-                               }
-
-                               //TODO: handle NoValueSnak and SomeValueSnak!
-                       }
-               }
-
-               // TODO: sitelinks, use skos:isPrimarySubjectOf or 
foaf:primaryTopic?
-               // + state language of resource
-               // TODO: use rdf:about (or what?!) to link subject URI to 
document URI
-
+               $graph = $builder->getGraph();
                return $graph;
        }
 
@@ -266,6 +182,9 @@
                return $data;
        }
 
+       /**
+        * @return string
+        */
        public function getDefaultMimeType() {
                return $this->format->getDefaultMimeType();
        }
diff --git a/repo/includes/specials/SpecialEntityData.php 
b/repo/includes/specials/SpecialEntityData.php
index 7b35bc1..fa0a084 100755
--- a/repo/includes/specials/SpecialEntityData.php
+++ b/repo/includes/specials/SpecialEntityData.php
@@ -63,6 +63,11 @@
        protected $dataTypeFactory = null;
 
        /**
+        * @var \Wikibase\Lib\EntityIdFormatter
+        */
+       protected $idFormatter = null;
+
+       /**
         * Constructor.
         *
         * @since 0.4
@@ -112,7 +117,7 @@
                $this->rdfBaseURI = $repo->getRdfBaseURI();
                $this->entityLookup = 
\Wikibase\StoreFactory::getStore()->getEntityLookup();
                $this->dataTypeFactory = $repo->getDataTypeFactory();
-
+               $this->idFormatter = $repo->getIdFormatter();
 
                $this->showData( $format, $id, $revision );
        }
@@ -291,7 +296,8 @@
                        $rdfFormat,
                        $this->rdfBaseURI,
                        $this->entityLookup,
-                       $this->dataTypeFactory
+                       $this->dataTypeFactory,
+                       $this->idFormatter
                );
 
                return $serializer;
diff --git a/repo/tests/phpunit/includes/content/RdfBuilderTest.php 
b/repo/tests/phpunit/includes/content/RdfBuilderTest.php
new file mode 100644
index 0000000..47827ad
--- /dev/null
+++ b/repo/tests/phpunit/includes/content/RdfBuilderTest.php
@@ -0,0 +1,271 @@
+<?php
+
+namespace Wikibase\Test;
+use DataTypes\DataTypeFactory;
+use EasyRdf_Namespace;
+use MediaWikiSite;
+use ValueFormatters\FormatterOptions;
+use Wikibase\Entity;
+use Wikibase\EntityId;
+use Wikibase\Item;
+use Wikibase\Lib\EntityIdFormatter;
+use Wikibase\Property;
+use Wikibase\RdfBuilder;
+
+/**
+ * Tests for the Wikibase\RdfBuilder class.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @since 0.4
+ *
+ * @ingroup WikibaseRepoTest
+ * @ingroup Test
+ * @ingroup RDF
+ *
+ * @group Wikibase
+ * @group WikibaseRepo
+ * @group WikibaseRdf
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class RdfBuilderTest extends \MediaWikiTestCase {
+
+       const URI_BASE = 'http://acme.test';
+
+       public function setUp() {
+               parent::setUp();
+
+               if ( !RdfBuilder::isSupported() ) {
+                       $this->markTestSkipped( "RDF library not found" );
+               }
+       }
+
+       /**
+        * @return Entity[]
+        */
+       public static function getTestEntities() {
+               static $entities = array();
+
+               if ( !empty( $entities ) ) {
+                       return $entities;
+               }
+
+               $entity = Item::newEmpty();
+               $entities['empty'] = $entity;
+
+
+               $entity = Item::newEmpty();
+               $entities['terms'] = $entity;
+
+               $entity->setLabel( 'en', 'Berlin' );
+               $entity->setLabel( 'ru', 'Берлин' );
+
+               $entity->setDescription( 'en', 'German city' );
+               $entity->setDescription( 'ru', 'столица и одновременно земля 
Германии' );
+
+               $entity->addAliases( 'en', array( 'Berlin, Germany', 'Land 
Berlin' ) );
+               $entity->addAliases( 'ru', array( 'Berlin' ) );
+
+               // TODO: test links
+               // TODO: test data values
+
+               $i = 1;
+               foreach ( $entities as $entity ) {
+                       $entity->setId( new EntityId( Item::ENTITY_TYPE, $i++ ) 
);
+               }
+
+               return $entities;
+       }
+
+       /**
+        * @param \Wikibase\EntityId $entityId
+        * @param array $properties
+        *
+        * @return \EasyRdf_Graph
+        */
+       protected static function makeEntityGraph( EntityId $entityId, 
$properties ) {
+               $graph = new \EasyRdf_Graph();
+
+               $builder = self::newRdfBuilder( 'rdf' ); //XXX: ugh, dummy 
object
+
+               $entityUri = $builder->getEntityQName( RdfBuilder::NS_ENTITY, 
$entityId );
+               $entityResource = $graph->resource( $entityUri );
+
+               /* @var \EasyRdf_Resource $entityResource */
+               foreach ( $properties as $prop => $values ) {
+                       if ( is_scalar( $values ) ) {
+                               $values = array( $values );
+                       }
+
+                       foreach ( $values as $val ) {
+                               if ( is_string( $val ) ) {
+                                       $val = $graph->resource( $val );
+                               }
+
+                               $entityResource->add( $prop, $val );
+                       }
+               }
+
+               return $graph;
+       }
+
+       /**
+        * @return \EasyRdf_Graph[]
+        */
+       public static function getTestGraphs() {
+               static $graphs = array();
+
+               if ( !empty( $graphs ) ) {
+                       return $graphs;
+               }
+
+               $builder = self::newRdfBuilder( 'rdf' ); //XXX: ugh, dummy 
object
+
+               foreach ( $builder->getNamespaces() as $gname => $uri ) {
+                       EasyRdf_Namespace::set( $gname, $uri );
+               }
+
+               $entities = self::getTestEntities();
+
+               $graphs['empty'] = self::makeEntityGraph(
+                       $entities['empty']->getId(),
+                       array(
+                               'rdf:type' => $builder->getEntityTypeQName( 
Item::ENTITY_TYPE ),
+                       )
+               );
+
+               $graphs['terms'] = self::makeEntityGraph(
+                       $entities['terms']->getId(),
+                       array(
+                               'rdf:type' => $builder->getEntityTypeQName( 
Item::ENTITY_TYPE ),
+                               'foaf:primaryTopicOf' => 
$builder->getEntityQName( RdfBuilder::NS_DATA, $entities['terms']->getId() ),
+                               'rdfs:label' => array(
+                                       new \EasyRdf_Literal( 'Berlin', 'en' ),
+                                       new \EasyRdf_Literal( 'Берлин', 'ru' )
+                               ),
+                               'skos:prefLabel' => array(
+                                       new \EasyRdf_Literal( 'Berlin', 'en' ),
+                                       new \EasyRdf_Literal( 'Берлин', 'ru' )
+                               ),
+                               'skos:note' => array(
+                                       new \EasyRdf_Literal( 'German city', 
'en' ),
+                                       new \EasyRdf_Literal( 'столица и 
одновременно земля Германии', 'ru' )
+                               ),
+                               'skos:altLabel' => array(
+                                       new \EasyRdf_Literal( 'Berlin, 
Germany', 'en' ),
+                                       new \EasyRdf_Literal( 'Land Berlin', 
'en' ),
+                                       new \EasyRdf_Literal( 'Berlin', 'ru' )
+                               ),
+                       )
+               );
+
+               // TODO: test links
+               // TODO: test data values
+
+               return $graphs;
+       }
+
+       /**
+        * @return RdfBuilder
+        */
+       protected static function newRdfBuilder() {
+               $idFormatter = new EntityIdFormatter( new FormatterOptions( 
array(
+                       EntityIdFormatter::OPT_PREFIX_MAP => array(
+                               Item::ENTITY_TYPE => 'q',
+                               Property::ENTITY_TYPE => 'p',
+                       )
+               ) ) );
+
+               return new RdfBuilder(
+                       self::URI_BASE,
+                       $idFormatter
+               );
+       }
+
+       public static function provideAddEntity() {
+               $entities = self::getTestEntities();
+               $graphs = self::getTestGraphs();
+
+               $cases = array();
+
+               foreach ( $entities as $name => $entity ) {
+                       $cases[] = array(
+                               $entity,
+                               $graphs[$name],
+                       );
+               }
+
+               return $cases;
+       }
+
+       /**
+        * @dataProvider provideAddEntity
+        */
+       public function testAddEntity( Entity $entity, \EasyRdf_Graph 
$expectedGraph ) {
+               $builder = $this->newRdfBuilder();
+
+               //TODO: also test revision meta data
+               $builder->addEntity( $entity );
+               $graph = $builder->getGraph();
+
+               foreach ( $expectedGraph->resources() as $rc ) {
+                       foreach ( $expectedGraph->properties( $rc ) as $prop ) {
+                               $expectedValues = $expectedGraph->all( $rc, 
$prop );
+                               $actualValues = $graph->all( $rc, $prop );
+
+                               $this->assertArrayEquals(
+                                       self::rdf2strings( $expectedValues ),
+                                       self::rdf2strings( $actualValues )
+                               );
+                       }
+               }
+       }
+
+       public static function rdf2strings( array $data ) {
+               $strings = array();
+
+               foreach ( $data as $obj ) {
+                       $strings[] = self::rdf2string( $obj );
+               }
+
+               return $strings;
+       }
+
+       public static function rdf2string( $obj ) {
+               if ( $obj instanceof \EasyRdf_Resource ) {
+                       return '<' . $obj->getUri() . '>';
+               } elseif ( $obj instanceof \EasyRdf_Literal ) {
+                       $s = '"' . $obj->getValue() . '"';
+
+                       if ( $obj->getDatatype() ) {
+                               $s .= '^^' . $obj->getDatatype();
+                       } elseif ( $obj->getLang() ) {
+                               $s .= '@' . $obj->getLang();
+                       }
+
+                       return $s;
+               } else {
+                       return strval( $obj );
+               }
+       }
+
+       //TODO: test resolveMentionedEntities
+       //TODO: test all the addXXX methods
+
+}
diff --git a/repo/tests/phpunit/includes/content/RdfSerializerTest.php 
b/repo/tests/phpunit/includes/content/RdfSerializerTest.php
index 7de00d5..9136029 100644
--- a/repo/tests/phpunit/includes/content/RdfSerializerTest.php
+++ b/repo/tests/phpunit/includes/content/RdfSerializerTest.php
@@ -4,9 +4,12 @@
 use DataTypes\DataTypeFactory;
 use EasyRdf_Namespace;
 use MediaWikiSite;
+use ValueFormatters\FormatterOptions;
 use Wikibase\Entity;
 use Wikibase\EntityId;
 use Wikibase\Item;
+use Wikibase\Lib\EntityIdFormatter;
+use Wikibase\Property;
 use Wikibase\RdfSerializer;
 use Wikibase\SiteLink;
 
@@ -33,12 +36,11 @@
  *
  * @ingroup WikibaseRepoTest
  * @ingroup Test
+ * @ingroup RDF
  *
  * @group Wikibase
  * @group WikibaseRepo
- * @group WikibaseProperty
- * @group WikibaseEntity
- * @group WikibaseEntityHandler
+ * @group WikibaseRdf
  *
  * @licence GNU GPL v2+
  * @author Daniel Kinzler
@@ -79,8 +81,6 @@
                ),
        );
 
-       protected static $uriBase = 'http://acme.test';
-
        public function setUp() {
                parent::setUp();
 
@@ -93,127 +93,14 @@
         * @return Entity[]
         */
        protected static function getTestEntities() {
-               static $entities = array();
-
-               if ( !empty( $entities ) ) {
-                       return $entities;
-               }
-
-               $entity = Item::newEmpty();
-               $entities['empty'] = $entity;
-
-
-               $entity = Item::newEmpty();
-               $entities['terms'] = $entity;
-
-               $entity->setLabel( 'en', 'Berlin' );
-               $entity->setLabel( 'ru', 'Берлин' );
-
-               $entity->setDescription( 'en', 'German city' );
-               $entity->setDescription( 'ru', 'столица и одновременно земля 
Германии' );
-
-               $entity->addAliases( 'en', array( 'Berlin, Germany', 'Land 
Berlin' ) );
-               $entity->addAliases( 'ru', array( 'Berlin' ) );
-
-               // not yet supported
-               /*
-               $entity = Item::newEmpty();
-               $entities['links'] = $entity;
-
-               $entity->setLabel( 'en', 'Berlin' );
-
-               $entity->addSiteLink( new SiteLink( 
MediaWikiSite::newFromGlobalId( 'enwiki' ), 'Berlin' ) );
-               $entity->addSiteLink( new SiteLink( 
MediaWikiSite::newFromGlobalId( 'dewiki' ), 'Berlin' ) );
-               $entity->addSiteLink( new SiteLink( 
MediaWikiSite::newFromGlobalId( 'ruwiki' ), 'Берлин' ) );
-               */
-
-               $i = 1;
-               foreach ( $entities as $entity ) {
-                       $entity->setId( new EntityId( Item::ENTITY_TYPE, $i++ ) 
);
-               }
-
-               return $entities;
-       }
-
-       /**
-        * @param \Wikibase\EntityId $entityId
-        * @param array $properties
-        *
-        * @return \EasyRdf_Graph
-        */
-       protected static function makeEntityGraph( EntityId $entityId, 
$properties ) {
-               $graph = new \EasyRdf_Graph();
-
-               $entityUri = 'wikibase_id:' . ucfirst( 
$entityId->getPrefixedId() );
-               $entityResource = $graph->resource( $entityUri );
-
-               /* @var \EasyRdf_Resource $entityResource */
-               foreach ( $properties as $prop => $values ) {
-                       if ( is_scalar( $values ) ) {
-                               $values = array( $values );
-                       }
-
-                       foreach ( $values as $val ) {
-                               $entityResource->add( $prop, $val );
-                       }
-               }
-
-               return $graph;
+               return RdfBuilderTest::getTestEntities();
        }
 
        /**
         * @return \EasyRdf_Graph[]
         */
        protected static function getTestGraphs() {
-               static $graphs = array();
-
-               if ( !empty( $graphs ) ) {
-                       return $graphs;
-               }
-
-               $serializer = self::newRdfSerializer( 'rdf' ); // dummy
-
-               foreach ( $serializer->getNamespaces() as $gname => $uri ) {
-                       EasyRdf_Namespace::set( $gname, $uri );
-               }
-
-               $entities = self::getTestEntities();
-
-               $graphs['empty'] = self::makeEntityGraph(
-                       $entities['empty']->getId(),
-                       array()
-               );
-
-               $graphs['terms'] = self::makeEntityGraph(
-                       $entities['terms']->getId(),
-                       array(
-                               'rdfs:label' => array(
-                                       new \EasyRdf_Literal( 'Berlin', 'en' ),
-                                       new \EasyRdf_Literal( 'Берлин', 'ru' )
-                               ),
-                               'rdfs:comment' => array(
-                                       new \EasyRdf_Literal( 'German city', 
'en' ),
-                                       new \EasyRdf_Literal( 'столица и 
одновременно земля Германии', 'ru' )
-                               ),
-                               'wikibase_ontology:knownAs' => array(
-                                       new \EasyRdf_Literal( 'Berlin, 
Germany', 'en' ),
-                                       new \EasyRdf_Literal( 'Land Berlin', 
'en' ),
-                                       new \EasyRdf_Literal( 'Berlin', 'ru' )
-                               ),
-                       )
-               );
-
-               // not yet supportted
-               /*
-               $graphs['links'] = self::makeEntityGraph(
-                       $entities['links']->getId(),
-                       array(
-                               //'rdfs:label', new \EasyRdf_Literal( '', '' )
-                       )
-               );
-               */
-
-               return $graphs;
+               return RdfBuilderTest::getTestGraphs();
        }
 
        protected static function getTestDataPatterns() {
@@ -223,26 +110,28 @@
                        return $patterns;
                }
 
-               $patterns['empty']['rdf'] = '!<rdf:RDF.*</rdf:RDF>!s';
-               $patterns['empty']['n3']  = '!!s';
+               $patterns['empty']['rdf'] = array( '!<rdf:RDF.*</rdf:RDF>!s' );
+               $patterns['empty']['n3']  = array( '!!s' );
 
-               $patterns['terms']['rdf'] = '!<rdf:RDF.*'
-                       . '<rdf:Description.*rdf:about="wikibase_id:Q2".*'
-                       . '<rdfs:label xml:lang="en">Berlin</rdfs:label>.*'
-                       . '<rdfs:comment xml:lang="en">German 
city</rdfs:comment>.*'
-                       . '<wikibase_ontology:knownAs xml:lang="en">Berlin, 
Germany</wikibase_ontology:knownAs>.*'
-                       . '</rdf:RDF>!s';
-               $patterns['terms']['n3']  = '!<wikibase_id:Q2>.*'
-                       . 'rdfs:label +"Berlin"@en,.*'
-                       . 'rdfs:comment +"German city"@en,.*'
-                       . 'wikibase_ontology:knownAs +"Berlin, Germany"@en,.*'
-                       . '!s';
+               $patterns['terms']['rdf'] = array(
+                       '!<rdf:RDF.*</rdf:RDF>!s',
+                       '!<wikibase:Item.*rdf:about=".*?entity/q2"!s',
+                       '!<rdfs:label xml:lang="en">Berlin</rdfs:label>!s',
+                       '!<skos:prefLabel 
xml:lang="en">Berlin</skos:prefLabel>!s',
+                       '!<skos:note xml:lang="en">German city</skos:note>!s',
+                       '!<skos:altLabel xml:lang="en">Berlin, 
Germany</skos:altLabel>!s',
+               );
 
-               // links not yet supported
-               /*
-               $patterns['links']['rdf'] = '!xxx!s';
-               $patterns['links']['n3']  = '!xxx!s';
-               */
+               $patterns['terms']['n3']  = array(
+                       '!entity:q2!s',
+                       '!rdfs:label +"Berlin"@en,!s',
+                       '!skos:prefLabel +"Berlin"@en,!s',
+                       '!skos:note +"German city"@en,!s',
+                       '!skos:altLabel +"Berlin, Germany"@en,!s',
+               );
+
+               // TODO: test links
+               // TODO: test data values
 
                return $patterns;
        }
@@ -252,6 +141,12 @@
                $format = RdfSerializer::getFormat( $formatName );
 
                $dataTypes = new DataTypeFactory( self::$dataTypes );
+               $idSerializer = new EntityIdFormatter( new FormatterOptions( 
array(
+                       EntityIdFormatter::OPT_PREFIX_MAP => array(
+                               Item::ENTITY_TYPE => 'q',
+                               Property::ENTITY_TYPE => 'p',
+                       )
+               ) ) );
 
                $mockRepo = new MockRepository();
 
@@ -261,9 +156,10 @@
 
                return new RdfSerializer(
                        $format,
-                       self::$uriBase,
+                       RdfBuilderTest::URI_BASE,
                        $mockRepo,
-                       $dataTypes
+                       $dataTypes,
+                       $idSerializer
                );
        }
 
@@ -314,7 +210,11 @@
                        foreach ( $expectedGraph->properties( $rc ) as $prop ) {
                                $expectedValues = $expectedGraph->all( $rc, 
$prop );
                                $actualValues = $graph->all( $rc, $prop );
-                               $this->assertArrayEquals( $expectedValues, 
$actualValues );
+
+                               $this->assertArrayEquals(
+                                       RdfBuilderTest::rdf2strings( 
$expectedValues ),
+                                       RdfBuilderTest::rdf2strings( 
$actualValues )
+                               );
                        }
                }
        }
@@ -343,11 +243,14 @@
        /**
         * @dataProvider provideSerializeRdf
         */
-       public function testSerializeRdf( \EasyRdf_Graph $graph, $format, 
$regex ) {
+       public function testSerializeRdf( \EasyRdf_Graph $graph, $format, 
$regexes ) {
                $serializer = self::newRdfSerializer( $format );
 
                $data = $serializer->serializeRdf( $graph );
-               $this->assertRegExp( $regex, $data );
+
+               foreach ( $regexes as $regex ) {
+                       $this->assertRegExp( $regex, $data );
+               }
        }
 
        public static function provideSerializeEntity() {
@@ -374,11 +277,14 @@
        /**
         * @dataProvider provideSerializeEntity
         */
-       public function TestSerializeEntity( Entity $entity, $format, $regex ) {
+       public function testSerializeEntity( Entity $entity, $format, $regexes 
) {
                $serializer = self::newRdfSerializer( $format );
 
                $data = $serializer->serializeEntity( $entity );
-               $this->assertRegExp( $regex, $data );
+
+               foreach ( $regexes as $regex ) {
+                       $this->assertRegExp( $regex, $data );
+               }
        }
 
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ibf1499d1f0742db7fbeb5cb3180552fc59cddb2d
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/Wikibase
Gerrit-Branch: master
Gerrit-Owner: Daniel Kinzler <[email protected]>
Gerrit-Reviewer: Daniel Werner <[email protected]>
Gerrit-Reviewer: Jeroen De Dauw <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to