4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * http://www.gnu.org/copyleft/gpl.html
22 namespace MediaWiki\Collation
;
25 use InvalidArgumentException
;
26 use MediaWiki\Config\ServiceOptions
;
27 use MediaWiki\HookContainer\HookContainer
;
28 use MediaWiki\HookContainer\HookRunner
;
29 use MediaWiki\MainConfigNames
;
30 use Wikimedia\ObjectFactory\ObjectFactory
;
33 * Common factory to construct collation classes.
37 class CollationFactory
{
39 * @internal For use by ServiceWiring
41 public const CONSTRUCTOR_OPTIONS
= [
42 MainConfigNames
::CategoryCollation
,
45 private const CORE_COLLATIONS
= [
47 'class' => \UppercaseCollation
::class,
53 'class' => \NumericUppercaseCollation
::class,
60 'class' => \IdentityCollation
::class,
66 'class' => \IcuCollation
::class,
74 'uca-default-u-kn' => [
75 'class' => \IcuCollation
::class,
84 'class' => \CollationCkb
::class,
90 'class' => \AbkhazUppercaseCollation
::class,
96 'class' => \BashkirUppercaseCollation
::class,
103 /** @var ServiceOptions */
106 /** @var ObjectFactory */
107 private $objectFactory;
109 /** @var HookRunner */
113 * @param ServiceOptions $options
114 * @param ObjectFactory $objectFactory
115 * @param HookContainer $hookContainer
117 public function __construct(
118 ServiceOptions
$options,
119 ObjectFactory
$objectFactory,
120 HookContainer
$hookContainer
122 $options->assertRequiredOptions( self
::CONSTRUCTOR_OPTIONS
);
123 $this->options
= $options;
124 $this->objectFactory
= $objectFactory;
125 $this->hookRunner
= new HookRunner( $hookContainer );
128 public function getCategoryCollation(): Collation
{
129 return $this->makeCollation( $this->getDefaultCollationName() );
132 public function getDefaultCollationName(): string {
133 return $this->options
->get( MainConfigNames
::CategoryCollation
);
136 public function makeCollation( string $collationName ): Collation
{
137 if ( isset( self
::CORE_COLLATIONS
[$collationName] ) ) {
138 return $this->instantiateCollation( self
::CORE_COLLATIONS
[$collationName] );
141 if ( preg_match( '/^uca-([A-Za-z@=-]+)$/', $collationName, $match ) ) {
142 return $this->instantiateCollation( [
143 'class' => \IcuCollation
::class,
151 } elseif ( preg_match( '/^remote-uca-([A-Za-z@=-]+)$/', $collationName, $match ) ) {
152 return $this->instantiateCollation( [
153 'class' => \RemoteIcuCollation
::class,
155 'ShellboxClientFactory'
163 // Provide a mechanism for extensions to hook in.
164 $collationObject = null;
165 $this->hookRunner
->onCollation__factory( $collationName, $collationObject );
167 if ( !$collationObject instanceof Collation
) {
168 throw new InvalidArgumentException( __METHOD__
. ": unknown collation type \"$collationName\"" );
171 return $collationObject;
178 private function instantiateCollation( $spec ): Collation
{
179 return $this->objectFactory
->createObject(
182 'assertClass' => Collation
::class