Completed
Push — master ( 5c18d0...3ae30d )
by
unknown
05:18
created

ConstraintReportFactory::getConstraintChecker()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
cc 2
eloc 16
nc 2
nop 0
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport;
4
5
use Config;
6
use DataValues\DataValueFactory;
7
use IBufferingStatsdDataFactory;
8
use MediaWiki\Logger\LoggerFactory;
9
use MediaWiki\MediaWikiServices;
10
use TitleParser;
11
use Wikibase\DataModel\Entity\EntityIdParser;
12
use Wikibase\DataModel\Services\Lookup\EntityLookup;
13
use Wikibase\DataModel\Services\Lookup\PropertyDataTypeLookup;
14
use Wikibase\Lib\Store\EntityNamespaceLookup;
15
use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataAccessor;
16
use Wikibase\Lib\Store\Sql\WikiPageEntityMetaDataLookup;
17
use Wikibase\Lib\Units\UnitConverter;
18
use Wikibase\Rdf\RdfVocabulary;
19
use Wikibase\Repo\WikibaseRepo;
20
use WikibaseQuality\ConstraintReport\Api\CachingResultsSource;
21
use WikibaseQuality\ConstraintReport\Api\CheckingResultsSource;
22
use WikibaseQuality\ConstraintReport\Api\ResultsCache;
23
use WikibaseQuality\ConstraintReport\Api\ResultsSource;
24
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\CitationNeededChecker;
25
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\EntityTypeChecker;
26
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\IntegerChecker;
27
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\NoBoundsChecker;
28
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\AllowedUnitsChecker;
29
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\NoneOfChecker;
30
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ReferenceChecker;
31
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\SingleBestValueChecker;
32
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorDeserializer;
33
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\ContextCursorSerializer;
34
use WikibaseQuality\ConstraintReport\ConstraintCheck\DelegatingConstraintChecker;
35
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConstraintParameterParser;
36
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\CommonsLinkChecker;
37
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\FormatChecker;
38
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\OneOfChecker;
39
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\QualifierChecker;
40
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\RangeChecker;
41
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\TypeChecker;
42
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ConflictsWithChecker;
43
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\QualifiersChecker;
44
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\TargetRequiredClaimChecker;
45
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ItemChecker;
46
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\MandatoryQualifiersChecker;
47
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ValueTypeChecker;
48
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\SymmetricChecker;
49
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\InverseChecker;
50
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\DiffWithinRangeChecker;
51
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\SingleValueChecker;
52
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\MultiValueChecker;
53
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\UniqueValueChecker;
54
use WikibaseQuality\ConstraintReport\ConstraintCheck\Checker\ValueOnlyChecker;
55
use WikibaseQuality\ConstraintReport\ConstraintCheck\ConstraintChecker;
56
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\ConnectionCheckerHelper;
57
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\LoggingHelper;
58
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\RangeCheckerHelper;
59
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\SparqlHelper;
60
use WikibaseQuality\ConstraintReport\ConstraintCheck\Helper\TypeCheckerHelper;
61
use Wikibase\DataModel\Services\Statement\StatementGuidParser;
62
use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageDeserializer;
63
use WikibaseQuality\ConstraintReport\ConstraintCheck\Message\ViolationMessageSerializer;
64
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultDeserializer;
65
use WikibaseQuality\ConstraintReport\ConstraintCheck\Result\CheckResultSerializer;
66
67
/**
68
 * Factory for {@link DelegatingConstraintChecker}
69
 * and {@link ConstraintRepository}.
70
 *
71
 * @license GPL-2.0-or-later
72
 */
73
class ConstraintReportFactory {
74
75
	// services created by this factory
76
77
	/**
78
	 * @var DelegatingConstraintChecker|null
79
	 */
80
	private $delegatingConstraintChecker;
81
82
	/**
83
	 * @var ConstraintChecker[]|null
84
	 */
85
	private $constraintCheckerMap;
86
87
	/**
88
	 * @var ConstraintRepository|null
89
	 */
90
	private $constraintRepository;
91
92
	/**
93
	 * @var LoggingHelper|null
94
	 */
95
	private $loggingHelper;
96
97
	/**
98
	 * @var CheckResultSerializer|null
99
	 */
100
	private $checkResultSerializer;
101
102
	/**
103
	 * @var CheckResultDeserializer|null
104
	 */
105
	private $checkResultDeserializer;
106
107
	/**
108
	 * @var WikiPageEntityMetaDataAccessor|null
109
	 */
110
	private $wikiPageEntityMetaDataAccessor;
111
112
	/**
113
	 * @var ResultsSource|null
114
	 */
115
	private $resultsSource;
116
117
	// services used by this factory
118
119
	/**
120
	 * @var EntityLookup
121
	 */
122
	private $lookup;
123
124
	/**
125
	 * @var PropertyDataTypeLookup
126
	 */
127
	private $propertyDataTypeLookup;
128
129
	/**
130
	 * @var StatementGuidParser
131
	 */
132
	private $statementGuidParser;
133
134
	/**
135
	 * @var Config
136
	 */
137
	private $config;
138
139
	/**
140
	 * @var ConstraintParameterParser
141
	 */
142
	private $constraintParameterParser;
143
144
	/**
145
	 * @var ViolationMessageSerializer
146
	 */
147
	private $violationMessageSerializer;
148
149
	/**
150
	 * @var ViolationMessageDeserializer
151
	 */
152
	private $violationMessageDeserializer;
153
154
	/**
155
	 * @var RdfVocabulary
156
	 */
157
	private $rdfVocabulary;
158
159
	/**
160
	 * @var EntityIdParser
161
	 */
162
	private $entityIdParser;
163
164
	/**
165
	 * @var TitleParser
166
	 */
167
	private $titleParser;
168
169
	/**
170
	 * @var UnitConverter|null
171
	 */
172
	private $unitConverter;
173
174
	/**
175
	 * @var DataValueFactory
176
	 */
177
	private $dataValueFactory;
178
179
	/**
180
	 * @var EntityNamespaceLookup
181
	 */
182
	private $entityNamespaceLookup;
183
184
	/**
185
	 * @var IBufferingStatsdDataFactory
186
	 */
187
	private $dataFactory;
188
189
	/**
190
	 * Returns the default instance.
191
	 * IMPORTANT: Use only when it is not feasible to inject an instance properly.
192
	 *
193
	 * @return self
194
	 */
195
	public static function getDefaultInstance() {
196
		static $instance = null;
197
198
		if ( $instance === null ) {
199
			$wikibaseRepo = WikibaseRepo::getDefaultInstance();
200
			$config = MediaWikiServices::getInstance()->getMainConfig();
201
			$titleParser = MediaWikiServices::getInstance()->getTitleParser();
202
			$violationMessageDeserializer = new ViolationMessageDeserializer(
203
				$wikibaseRepo->getEntityIdParser(),
204
				$wikibaseRepo->getDataValueFactory()
205
			);
206
			$instance = new self(
207
				$wikibaseRepo->getEntityLookup(),
208
				$wikibaseRepo->getPropertyDataTypeLookup(),
209
				$wikibaseRepo->getStatementGuidParser(),
210
				$config,
211
				new ConstraintParameterParser(
212
					$config,
213
					$wikibaseRepo->getBaseDataModelDeserializerFactory(),
214
					$wikibaseRepo->getConceptBaseUris()
215
				),
216
				new ViolationMessageSerializer(),
217
				$violationMessageDeserializer,
218
				$wikibaseRepo->getRdfVocabulary(),
219
				$wikibaseRepo->getEntityIdParser(),
220
				$titleParser,
221
				$wikibaseRepo->getUnitConverter(),
222
				$wikibaseRepo->getDataValueFactory(),
223
				$wikibaseRepo->getEntityNamespaceLookup(),
224
				MediaWikiServices::getInstance()->getStatsdDataFactory()
225
			);
226
		}
227
228
		return $instance;
229
	}
230
231
	public function __construct(
232
		EntityLookup $lookup,
233
		PropertyDataTypeLookup $propertyDataTypeLookup,
234
		StatementGuidParser $statementGuidParser,
235
		Config $config,
236
		ConstraintParameterParser $constraintParameterParser,
237
		ViolationMessageSerializer $violationMessageSerializer,
238
		ViolationMessageDeserializer $violationMessageDeserializer,
239
		RdfVocabulary $rdfVocabulary,
240
		EntityIdParser $entityIdParser,
241
		TitleParser $titleParser,
242
		UnitConverter $unitConverter = null,
243
		DataValueFactory $dataValueFactory,
244
		EntityNamespaceLookup $entityNamespaceLookup,
245
		IBufferingStatsdDataFactory $dataFactory
246
	) {
247
		$this->lookup = $lookup;
248
		$this->propertyDataTypeLookup = $propertyDataTypeLookup;
249
		$this->statementGuidParser = $statementGuidParser;
250
		$this->config = $config;
251
		$this->constraintParameterParser = $constraintParameterParser;
252
		$this->violationMessageSerializer = $violationMessageSerializer;
253
		$this->violationMessageDeserializer = $violationMessageDeserializer;
254
		$this->rdfVocabulary = $rdfVocabulary;
255
		$this->entityIdParser = $entityIdParser;
256
		$this->titleParser = $titleParser;
257
		$this->unitConverter = $unitConverter;
258
		$this->dataValueFactory = $dataValueFactory;
259
		$this->entityNamespaceLookup = $entityNamespaceLookup;
260
		$this->dataFactory = $dataFactory;
261
	}
262
263
	/**
264
	 * @return DelegatingConstraintChecker
265
	 */
266
	public function getConstraintChecker() {
267
		if ( $this->delegatingConstraintChecker === null ) {
268
			$this->delegatingConstraintChecker = new DelegatingConstraintChecker(
269
				$this->lookup,
270
				$this->getConstraintCheckerMap(),
271
				new CachingConstraintLookup( $this->getConstraintRepository() ),
272
				$this->constraintParameterParser,
273
				$this->statementGuidParser,
274
				new LoggingHelper(
275
					$this->dataFactory,
276
					LoggerFactory::getInstance( 'WikibaseQualityConstraints' ),
277
					$this->config
278
				),
279
				$this->config->get( 'WBQualityConstraintsCheckQualifiers' ),
280
				$this->config->get( 'WBQualityConstraintsCheckReferences' ),
281
				$this->config->get( 'WBQualityConstraintsPropertiesWithViolatingQualifiers' )
282
			);
283
		}
284
285
		return $this->delegatingConstraintChecker;
286
	}
287
288
	/**
289
	 * @return ConstraintChecker[]
290
	 */
291
	private function getConstraintCheckerMap() {
292
		if ( $this->constraintCheckerMap === null ) {
293
			$connectionCheckerHelper = new ConnectionCheckerHelper();
294
			$rangeCheckerHelper = new RangeCheckerHelper( $this->config, $this->unitConverter );
295
			if ( $this->config->get( 'WBQualityConstraintsSparqlEndpoint' ) !== '' ) {
296
				$sparqlHelper = new SparqlHelper(
297
					$this->config,
298
					$this->rdfVocabulary,
299
					$this->entityIdParser,
300
					$this->propertyDataTypeLookup,
301
					MediaWikiServices::getInstance()->getMainWANObjectCache(),
302
					$this->violationMessageSerializer,
303
					$this->violationMessageDeserializer,
304
					$this->dataFactory
305
				);
306
			} else {
307
				$sparqlHelper = null;
308
			}
309
			$typeCheckerHelper = new TypeCheckerHelper(
310
				$this->lookup,
311
				$this->config,
312
				$sparqlHelper,
313
				$this->dataFactory
314
			);
315
316
			$this->constraintCheckerMap = [
317
				$this->config->get( 'WBQualityConstraintsConflictsWithConstraintId' )
318
					=> new ConflictsWithChecker(
319
						$this->lookup,
320
						$this->constraintParameterParser,
321
						$connectionCheckerHelper
322
					),
323
				$this->config->get( 'WBQualityConstraintsItemRequiresClaimConstraintId' )
324
					=> new ItemChecker(
325
						$this->lookup,
326
						$this->constraintParameterParser,
327
						$connectionCheckerHelper
328
					),
329
				$this->config->get( 'WBQualityConstraintsValueRequiresClaimConstraintId' )
330
					=> new TargetRequiredClaimChecker(
331
						$this->lookup,
332
						$this->constraintParameterParser,
333
						$connectionCheckerHelper
334
					),
335
				$this->config->get( 'WBQualityConstraintsSymmetricConstraintId' )
336
					=> new SymmetricChecker(
337
						$this->lookup,
338
						$connectionCheckerHelper
339
					),
340
				$this->config->get( 'WBQualityConstraintsInverseConstraintId' )
341
					=> new InverseChecker(
342
						$this->lookup,
343
						$this->constraintParameterParser,
344
						$connectionCheckerHelper
345
					),
346
				$this->config->get( 'WBQualityConstraintsUsedAsQualifierConstraintId' )
347
					=> new QualifierChecker(),
348
				$this->config->get( 'WBQualityConstraintsAllowedQualifiersConstraintId' )
349
					=> new QualifiersChecker(
350
						$this->constraintParameterParser
351
					),
352
				$this->config->get( 'WBQualityConstraintsMandatoryQualifierConstraintId' )
353
					=> new MandatoryQualifiersChecker(
354
						$this->constraintParameterParser
355
					),
356
				$this->config->get( 'WBQualityConstraintsRangeConstraintId' )
357
					=> new RangeChecker(
358
						$this->propertyDataTypeLookup,
359
						$this->constraintParameterParser,
360
						$rangeCheckerHelper
361
					),
362
				$this->config->get( 'WBQualityConstraintsDifferenceWithinRangeConstraintId' )
363
					=> new DiffWithinRangeChecker(
364
						$this->constraintParameterParser,
365
						$rangeCheckerHelper,
366
						$this->config
367
					),
368
				$this->config->get( 'WBQualityConstraintsTypeConstraintId' )
369
					=> new TypeChecker(
370
						$this->lookup,
371
						$this->constraintParameterParser,
372
						$typeCheckerHelper,
373
						$this->config
374
					),
375
				$this->config->get( 'WBQualityConstraintsValueTypeConstraintId' )
376
					=> new ValueTypeChecker(
377
						$this->lookup,
378
						$this->constraintParameterParser,
379
						$typeCheckerHelper,
380
						$this->config
381
					),
382
				$this->config->get( 'WBQualityConstraintsSingleValueConstraintId' )
383
					=> new SingleValueChecker( $this->constraintParameterParser ),
384
				$this->config->get( 'WBQualityConstraintsMultiValueConstraintId' )
385
					=> new MultiValueChecker( $this->constraintParameterParser ),
386
				$this->config->get( 'WBQualityConstraintsDistinctValuesConstraintId' )
387
					=> new UniqueValueChecker(
388
						$sparqlHelper
389
					),
390
				$this->config->get( 'WBQualityConstraintsFormatConstraintId' )
391
					=> new FormatChecker(
392
						$this->constraintParameterParser,
393
						$this->config,
394
						$sparqlHelper
395
					),
396
				$this->config->get( 'WBQualityConstraintsCommonsLinkConstraintId' )
397
					=> new CommonsLinkChecker(
398
						$this->constraintParameterParser,
399
						$this->titleParser
400
					),
401
				$this->config->get( 'WBQualityConstraintsOneOfConstraintId' )
402
					=> new OneOfChecker(
403
						$this->constraintParameterParser
404
					),
405
				$this->config->get( 'WBQualityConstraintsUsedForValuesOnlyConstraintId' )
406
					=> new ValueOnlyChecker(),
407
				$this->config->get( 'WBQualityConstraintsUsedAsReferenceConstraintId' )
408
					=> new ReferenceChecker(),
409
				$this->config->get( 'WBQualityConstraintsNoBoundsConstraintId' )
410
					=> new NoBoundsChecker(),
411
				$this->config->get( 'WBQualityConstraintsAllowedUnitsConstraintId' )
412
					=> new AllowedUnitsChecker(
413
						$this->constraintParameterParser,
414
						$this->unitConverter
415
					),
416
				$this->config->get( 'WBQualityConstraintsSingleBestValueConstraintId' )
417
					=> new SingleBestValueChecker( $this->constraintParameterParser ),
418
				$this->config->get( 'WBQualityConstraintsAllowedEntityTypesConstraintId' )
419
					=> new EntityTypeChecker(
420
						$this->constraintParameterParser
421
					),
422
				$this->config->get( 'WBQualityConstraintsNoneOfConstraintId' )
423
					=> new NoneOfChecker(
424
						$this->constraintParameterParser
425
					),
426
				$this->config->get( 'WBQualityConstraintsIntegerConstraintId' )
427
					=> new IntegerChecker(),
428
				$this->config->get( 'WBQualityConstraintsCitationNeededConstraintId' )
429
					=> new CitationNeededChecker(),
430
			];
431
		}
432
433
		return $this->constraintCheckerMap;
434
	}
435
436
	/**
437
	 * @return ConstraintRepository
438
	 */
439
	public function getConstraintRepository() {
440
		if ( $this->constraintRepository === null ) {
441
			$this->constraintRepository = new ConstraintRepository();
442
		}
443
444
		return $this->constraintRepository;
445
	}
446
447
	/**
448
	 * @return LoggingHelper
449
	 */
450
	public function getLoggingHelper() {
451
		if ( $this->loggingHelper === null ) {
452
			$this->loggingHelper = new LoggingHelper(
453
				$this->dataFactory,
454
				LoggerFactory::getInstance( 'WikibaseQualityConstraints' ),
455
				$this->config
456
			);
457
		}
458
459
		return $this->loggingHelper;
460
	}
461
462
	/**
463
	 * @return CheckResultSerializer
464
	 */
465
	public function getCheckResultSerializer() {
466
		if ( $this->checkResultSerializer === null ) {
467
			$this->checkResultSerializer = new CheckResultSerializer(
468
				new ConstraintSerializer(
469
					false // constraint parameters are not exposed
470
				),
471
				new ContextCursorSerializer(),
472
				new ViolationMessageSerializer(),
473
				false // unnecessary to serialize individual result dependencies
474
			);
475
		}
476
477
		return $this->checkResultSerializer;
478
	}
479
480
	/**
481
	 * @return CheckResultDeserializer
482
	 */
483
	public function getCheckResultDeserializer() {
484
		if ( $this->checkResultDeserializer === null ) {
485
			$this->checkResultDeserializer = new CheckResultDeserializer(
486
				new ConstraintDeserializer(),
487
				new ContextCursorDeserializer(),
488
				new ViolationMessageDeserializer(
489
					$this->entityIdParser,
490
					$this->dataValueFactory
491
				),
492
				$this->entityIdParser
493
			);
494
		}
495
496
		return $this->checkResultDeserializer;
497
	}
498
499
	/**
500
	 * @return WikiPageEntityMetaDataAccessor
501
	 */
502
	public function getWikiPageEntityMetaDataAccessor() {
503
		if ( $this->wikiPageEntityMetaDataAccessor === null ) {
504
			$this->wikiPageEntityMetaDataAccessor = new WikiPageEntityMetaDataLookup(
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Wikibase\Lib\Store\...>entityNamespaceLookup) of type object<Wikibase\Lib\Stor...geEntityMetaDataLookup> is incompatible with the declared type object<Wikibase\Lib\Stor...yMetaDataAccessor>|null of property $wikiPageEntityMetaDataAccessor.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
505
				$this->entityNamespaceLookup
506
			);
507
		}
508
509
		return $this->wikiPageEntityMetaDataAccessor;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->wikiPageEntityMetaDataAccessor; of type Wikibase\Lib\Store\Sql\W...eEntityMetaDataAccessor adds the type Wikibase\Lib\Store\Sql\W...ageEntityMetaDataLookup to the return on line 509 which is incompatible with the return type documented by WikibaseQuality\Constrai...eEntityMetaDataAccessor of type Wikibase\Lib\Store\Sql\W...eEntityMetaDataAccessor.
Loading history...
510
	}
511
512
	/**
513
	 * @return ResultsSource
514
	 */
515
	public function getResultsSource() {
516
		if ( $this->resultsSource === null ) {
517
			$this->resultsSource = new CheckingResultsSource(
518
				$this->getConstraintChecker()
519
			);
520
521
			if ( $this->config->get( 'WBQualityConstraintsCacheCheckConstraintsResults' ) ) {
522
				$this->resultsSource = new CachingResultsSource(
523
					$this->resultsSource,
524
					ResultsCache::getDefaultInstance(),
525
					$this->getCheckResultSerializer(),
526
					$this->getCheckResultDeserializer(),
527
					$this->getWikiPageEntityMetaDataAccessor(),
528
					$this->entityIdParser,
529
					$this->config->get( 'WBQualityConstraintsCacheCheckConstraintsTTLSeconds' ),
530
					$this->getPossiblyStaleConstraintTypes(),
531
					$this->config->get( 'WBQualityConstraintsCacheCheckConstraintsMaximumRevisionIds' ),
532
					$this->getLoggingHelper()
533
				);
534
			}
535
		}
536
537
		return $this->resultsSource;
538
	}
539
540
	/**
541
	 * @return string[]
542
	 */
543
	public function getPossiblyStaleConstraintTypes() {
544
		return [
545
			$this->config->get( 'WBQualityConstraintsCommonsLinkConstraintId' ),
546
			$this->config->get( 'WBQualityConstraintsTypeConstraintId' ),
547
			$this->config->get( 'WBQualityConstraintsValueTypeConstraintId' ),
548
			$this->config->get( 'WBQualityConstraintsDistinctValuesConstraintId' ),
549
		];
550
	}
551
552
}
553