Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
88 / 88
100.00% covered (success)
100.00%
17 / 17
CRAP
100.00% covered (success)
100.00%
1 / 1
LexemeSpecificComponentsRdfBuilder
100.00% covered (success)
100.00%
88 / 88
100.00% covered (success)
100.00%
17 / 17
26
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 addPrefixes
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addEntity
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 addLexeme
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 addLexemeTypes
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addLemmas
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 addLanguage
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addLexicalCategory
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addForms
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 addSenses
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 addForm
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 addFormTypes
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addRepresentations
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 addGrammaticalFeatures
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 addSense
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 addSenseTypes
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addGlosses
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Wikibase\Lexeme\Presentation\Rdf;
4
5use Wikibase\DataModel\Entity\EntityDocument;
6use Wikibase\DataModel\Entity\ItemId;
7use Wikibase\DataModel\Term\TermList;
8use Wikibase\Lexeme\Domain\Model\Form;
9use Wikibase\Lexeme\Domain\Model\FormSet;
10use Wikibase\Lexeme\Domain\Model\Lexeme;
11use Wikibase\Lexeme\Domain\Model\Sense;
12use Wikibase\Lexeme\Domain\Model\SenseSet;
13use Wikibase\Repo\Rdf\EntityMentionListener;
14use Wikibase\Repo\Rdf\EntityRdfBuilder;
15use Wikibase\Repo\Rdf\RdfVocabulary;
16use Wikimedia\Assert\Assert;
17use Wikimedia\Purtle\RdfWriter;
18
19/**
20 * Rdf builder for parts of lexeme
21 *
22 * @license GPL-2.0-or-later
23 * @author Thomas Pellissier Tanon
24 * @author Amir Sarabadani <ladsgroup@gmail.com>
25 */
26class LexemeSpecificComponentsRdfBuilder implements EntityRdfBuilder {
27
28    private const NS_ONTOLEX = 'ontolex';
29    private const NS_DUBLIN_CORE_TERM = 'dct';
30
31    /**
32     * @var RdfVocabulary
33     */
34    private $vocabulary;
35
36    /**
37     * @var RdfWriter
38     */
39    private $writer;
40
41    /**
42     * @var EntityMentionListener
43     */
44    private $entityMentionTracker;
45
46    public function __construct(
47        RdfVocabulary $vocabulary,
48        RdfWriter $writer,
49        EntityMentionListener $entityMentionTracker
50    ) {
51        $this->vocabulary = $vocabulary;
52        $this->writer = $writer;
53        $this->entityMentionTracker = $entityMentionTracker;
54    }
55
56    /**
57     * Adds the prefixes used by the lexeme RDF mapping to the writer
58     * It should be executed before the writer starts
59     */
60    public function addPrefixes() {
61        $this->writer->prefix( self::NS_ONTOLEX, 'http://www.w3.org/ns/lemon/ontolex#' );
62        $this->writer->prefix( self::NS_DUBLIN_CORE_TERM, 'http://purl.org/dc/terms/' );
63    }
64
65    /**
66     * Map WikibaseLexeme entities to the RDF graph
67     *
68     * @param EntityDocument $entity
69     */
70    public function addEntity( EntityDocument $entity ) {
71        if ( $entity instanceof Lexeme ) {
72            $this->addLexeme( $entity );
73        }
74        if ( $entity instanceof Form ) {
75            $this->addForm( $entity );
76        }
77        if ( $entity instanceof Sense ) {
78            $this->addSense( $entity );
79        }
80    }
81
82    /**
83     * Map a Lexeme to the RDF graph
84     *
85     * @param Lexeme $lexeme
86     */
87    private function addLexeme( Lexeme $lexeme ) {
88        $lexemeId = $lexeme->getId();
89        Assert::parameter( $lexemeId !== null, '$lexeme', 'must have a lexeme ID' );
90        $lexemeLName = $this->vocabulary->getEntityLName( $lexemeId );
91        $repositoryName = $this->vocabulary->getEntityRepositoryName( $lexemeId );
92        $lexemePrefix = $this->vocabulary->entityNamespaceNames[$repositoryName];
93
94        $this->addLexemeTypes( $lexemePrefix, $lexemeLName );
95        $this->addLemmas( $lexemePrefix, $lexemeLName, $lexeme->getLemmas() );
96        $this->addLanguage( $lexemePrefix, $lexemeLName, $lexeme->getLanguage() );
97        $this->addLexicalCategory( $lexemePrefix, $lexemeLName, $lexeme->getLexicalCategory() );
98        $this->addForms( $lexemePrefix, $lexemeLName, $lexeme->getForms() );
99        $this->addSenses( $lexemePrefix, $lexemeLName, $lexeme->getSenses() );
100    }
101
102    /**
103     * Adds the types of the given lexeme to the RDF graph
104     *
105     * @param string $lexemePrefix
106     * @param string $lexemeLName
107     */
108    private function addLexemeTypes( $lexemePrefix, $lexemeLName ) {
109        $this->writer->about( $lexemePrefix, $lexemeLName )
110            ->a( self::NS_ONTOLEX, 'LexicalEntry' );
111    }
112
113    /**
114     * Adds the lemmas of the given lexeme to the RDF graph
115     *
116     * @param string $lexemePrefix
117     * @param string $lexemeLName
118     * @param TermList $lemmas
119     */
120    private function addLemmas( $lexemePrefix, $lexemeLName, TermList $lemmas ) {
121        foreach ( $lemmas->toTextArray() as $lemmaCode => $lemmaText ) {
122            $this->writer->about( $lexemePrefix, $lexemeLName )
123                ->say( 'rdfs', 'label' )
124                ->text( $lemmaText, $lemmaCode )
125                ->say( RdfVocabulary::NS_ONTOLOGY, 'lemma' )
126                ->text( $lemmaText, $lemmaCode );
127        }
128    }
129
130    /**
131     * Adds the language of the given lexeme to the RDF graph
132     *
133     * @param string $lexemePrefix
134     * @param string $lexemeLName
135     * @param ItemId $language
136     */
137    private function addLanguage( $lexemePrefix, $lexemeLName, ItemId $language ) {
138        $languageLName = $this->vocabulary->getEntityLName( $language );
139        $this->entityMentionTracker->entityReferenceMentioned( $language );
140        $repositoryName = $this->vocabulary->getEntityRepositoryName( $language );
141
142        $this->writer->about( $lexemePrefix, $lexemeLName )
143            ->say( self::NS_DUBLIN_CORE_TERM, 'language' )
144            ->is( $this->vocabulary->entityNamespaceNames[$repositoryName], $languageLName );
145    }
146
147    /**
148     * Adds the lexical category of the given lexeme to the RDF graph
149     *
150     * @param string $lexemePrefix
151     * @param string $lexemeLName
152     * @param ItemId $lexicalCategory
153     */
154    private function addLexicalCategory( $lexemePrefix, $lexemeLName, ItemId $lexicalCategory ) {
155        $lexicalCategoryLName = $this->vocabulary->getEntityLName( $lexicalCategory );
156        $this->entityMentionTracker->entityReferenceMentioned( $lexicalCategory );
157        $repositoryName = $this->vocabulary->getEntityRepositoryName( $lexicalCategory );
158
159        $this->writer->about( $lexemePrefix, $lexemeLName )
160            ->say( RdfVocabulary::NS_ONTOLOGY, 'lexicalCategory' )
161            ->is( $this->vocabulary->entityNamespaceNames[$repositoryName], $lexicalCategoryLName );
162    }
163
164    /**
165     * Adds the forms of the given lexeme to the RDF graph
166     *
167     * @param string $lexemePrefix
168     * @param string $lexemeLName
169     * @param FormSet $forms
170     */
171    private function addForms( $lexemePrefix, $lexemeLName, FormSet $forms ) {
172        foreach ( $forms->toArray() as $form ) {
173            $this->entityMentionTracker->subEntityMentioned( $form );
174
175            $formLName = $this->vocabulary->getEntityLName( $form->getId() );
176            $this->writer->about( $lexemePrefix, $lexemeLName )
177                ->say( self::NS_ONTOLEX, 'lexicalForm' )
178                ->is( $lexemePrefix, $formLName );
179        }
180    }
181
182    /**
183     * Adds the senses of the given lexeme to the RDF graph
184     *
185     * @param string $lexemePrefix
186     * @param string $lexemeLName
187     * @param SenseSet $senses
188     */
189    private function addSenses( $lexemePrefix, $lexemeLName, SenseSet $senses ) {
190        foreach ( $senses->toArray() as $sense ) {
191            $this->entityMentionTracker->subEntityMentioned( $sense );
192
193            $senseLName = $this->vocabulary->getEntityLName( $sense->getId() );
194            $this->writer->about( $lexemePrefix, $lexemeLName )
195                ->say( self::NS_ONTOLEX, 'sense' )
196                ->is( $lexemePrefix, $senseLName );
197        }
198    }
199
200    /**
201     * Map a Form to the RDF graph
202     *
203     * @param Form $form
204     */
205    private function addForm( Form $form ) {
206        $formLName = $this->vocabulary->getEntityLName( $form->getId() );
207        $repositoryName = $this->vocabulary->getEntityRepositoryName( $form->getId() );
208        $lexemePrefix = $this->vocabulary->entityNamespaceNames[$repositoryName];
209
210        $this->addFormTypes( $lexemePrefix, $formLName );
211        $this->addRepresentations( $lexemePrefix, $formLName, $form->getRepresentations() );
212        $this->addGrammaticalFeatures( $lexemePrefix, $formLName, $form->getGrammaticalFeatures() );
213    }
214
215    /**
216     * Adds the types of the given form to the RDF graph
217     *
218     * @param string $lexemePrefix
219     * @param string $formLName
220     */
221    private function addFormTypes( $lexemePrefix, $formLName ) {
222        $this->writer->about( $lexemePrefix, $formLName )
223            ->a( self::NS_ONTOLEX, 'Form' );
224    }
225
226    /**
227     * Adds the representations of the given form to the RDF graph
228     *
229     * @param string $lexemePrefix
230     * @param string $formLName
231     * @param TermList $representations
232     */
233    private function addRepresentations( $lexemePrefix, $formLName, TermList $representations ) {
234        foreach ( $representations->toTextArray() as $representationCode => $representationText ) {
235            $this->writer->about( $lexemePrefix, $formLName )
236                ->say( 'rdfs', 'label' )
237                ->text( $representationText, $representationCode )
238                ->say( self::NS_ONTOLEX, 'representation' )
239                ->text( $representationText, $representationCode );
240        }
241    }
242
243    /**
244     * Adds the grammatical features of the given form to the RDF graph
245     *
246     * @param string $lexemePrefix
247     * @param string $formLName
248     * @param ItemId[] $grammaticalFeatures
249     */
250    private function addGrammaticalFeatures( $lexemePrefix, $formLName, array $grammaticalFeatures ) {
251        foreach ( $grammaticalFeatures as $grammaticalFeature ) {
252            $grammaticalFeatureLName = $this->vocabulary->getEntityLName( $grammaticalFeature );
253            $this->entityMentionTracker->entityReferenceMentioned( $grammaticalFeature );
254            $repositoryName = $this->vocabulary->getEntityRepositoryName( $grammaticalFeature );
255
256            $this->writer->about( $lexemePrefix, $formLName )
257                ->say( RdfVocabulary::NS_ONTOLOGY, 'grammaticalFeature' )
258                ->is( $this->vocabulary->entityNamespaceNames[$repositoryName], $grammaticalFeatureLName );
259        }
260    }
261
262    /**
263     * Map a Sense to the RDF graph
264     *
265     * @param Sense $sense
266     */
267    private function addSense( Sense $sense ) {
268        $senseLName = $this->vocabulary->getEntityLName( $sense->getId() );
269        $repositoryName = $this->vocabulary->getEntityRepositoryName( $sense->getId() );
270        $lexemePrefix = $this->vocabulary->entityNamespaceNames[$repositoryName];
271
272        $this->addSenseTypes( $lexemePrefix, $senseLName );
273        $this->addGlosses( $lexemePrefix, $senseLName, $sense->getGlosses() );
274    }
275
276    /**
277     * Adds the types of the given sense to the RDF graph
278     *
279     * @param string $lexemePrefix
280     * @param string $senseLName
281     */
282    private function addSenseTypes( $lexemePrefix, $senseLName ) {
283        $this->writer->about( $lexemePrefix, $senseLName )
284            ->a( self::NS_ONTOLEX, 'LexicalSense' );
285    }
286
287    /**
288     * Adds the glosses of the given sense to the RDF graph
289     *
290     * @param string $lexemePrefix
291     * @param string $senseLName
292     * @param TermList $glosses
293     */
294    private function addGlosses( $lexemePrefix, $senseLName, TermList $glosses ) {
295        foreach ( $glosses->toTextArray() as $glossCode => $glossText ) {
296            $this->writer->about( $lexemePrefix, $senseLName )
297                ->say( 'rdfs', 'label' )
298                ->text( $glossText, $glossCode )
299                ->say( RdfVocabulary::NS_SKOS, 'definition' )
300                ->text( $glossText, $glossCode );
301        }
302    }
303}