From: Reedy Date: Thu, 22 Sep 2016 23:35:52 +0000 (+0100) Subject: Rename includes/Services to includes/services for consistency X-Git-Tag: 1.31.0-rc.0~5370^2 X-Git-Url: http://git.cyclocoop.org/%22.htmlspecialchars%28%24url_syndic%29.%22?a=commitdiff_plain;h=a0fa3e4dc04d7ae59ab3aeb5f69303a96b073032;p=lhc%2Fweb%2Fwiklou.git Rename includes/Services to includes/services for consistency Change-Id: I900fab26a7cf5a339233f55c31168f8c2963bc8c --- diff --git a/autoload.php b/autoload.php index d985ee0ab0..a352884aa0 100644 --- a/autoload.php +++ b/autoload.php @@ -869,14 +869,14 @@ $wgAutoloadLocalClasses = [ 'MediaWiki\\Logger\\Spi' => __DIR__ . '/includes/debug/logger/Spi.php', 'MediaWiki\\MediaWikiServices' => __DIR__ . '/includes/MediaWikiServices.php', 'MediaWiki\\Search\\ParserOutputSearchDataExtractor' => __DIR__ . '/includes/search/ParserOutputSearchDataExtractor.php', - 'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/Services/CannotReplaceActiveServiceException.php', - 'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/Services/ContainerDisabledException.php', - 'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/Services/DestructibleService.php', - 'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/Services/NoSuchServiceException.php', - 'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/Services/SalvageableService.php', - 'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/Services/ServiceAlreadyDefinedException.php', - 'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/Services/ServiceContainer.php', - 'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/Services/ServiceDisabledException.php', + 'MediaWiki\\Services\\CannotReplaceActiveServiceException' => __DIR__ . '/includes/services/CannotReplaceActiveServiceException.php', + 'MediaWiki\\Services\\ContainerDisabledException' => __DIR__ . '/includes/services/ContainerDisabledException.php', + 'MediaWiki\\Services\\DestructibleService' => __DIR__ . '/includes/services/DestructibleService.php', + 'MediaWiki\\Services\\NoSuchServiceException' => __DIR__ . '/includes/services/NoSuchServiceException.php', + 'MediaWiki\\Services\\SalvageableService' => __DIR__ . '/includes/services/SalvageableService.php', + 'MediaWiki\\Services\\ServiceAlreadyDefinedException' => __DIR__ . '/includes/services/ServiceAlreadyDefinedException.php', + 'MediaWiki\\Services\\ServiceContainer' => __DIR__ . '/includes/services/ServiceContainer.php', + 'MediaWiki\\Services\\ServiceDisabledException' => __DIR__ . '/includes/services/ServiceDisabledException.php', 'MediaWiki\\Session\\BotPasswordSessionProvider' => __DIR__ . '/includes/session/BotPasswordSessionProvider.php', 'MediaWiki\\Session\\CookieSessionProvider' => __DIR__ . '/includes/session/CookieSessionProvider.php', 'MediaWiki\\Session\\ImmutableSessionProviderWithCookie' => __DIR__ . '/includes/session/ImmutableSessionProviderWithCookie.php', diff --git a/includes/Services/CannotReplaceActiveServiceException.php b/includes/Services/CannotReplaceActiveServiceException.php deleted file mode 100644 index 499307372d..0000000000 --- a/includes/Services/CannotReplaceActiveServiceException.php +++ /dev/null @@ -1,43 +0,0 @@ -destroy() - * after carefully detaching all relevant resources. - * - * @param SalvageableService $other The object to salvage state from. $other must have the - * exact same type as $this. - */ - public function salvage( SalvageableService $other ); - -} diff --git a/includes/Services/ServiceAlreadyDefinedException.php b/includes/Services/ServiceAlreadyDefinedException.php deleted file mode 100644 index c6344d3955..0000000000 --- a/includes/Services/ServiceAlreadyDefinedException.php +++ /dev/null @@ -1,45 +0,0 @@ -extraInstantiationParams = $extraInstantiationParams; - } - - /** - * Destroys all contained service instances that implement the DestructibleService - * interface. This will render all services obtained from this MediaWikiServices - * instance unusable. In particular, this will disable access to the storage backend - * via any of these services. Any future call to getService() will throw an exception. - * - * @see resetGlobalInstance() - */ - public function destroy() { - foreach ( $this->getServiceNames() as $name ) { - $service = $this->peekService( $name ); - if ( $service !== null && $service instanceof DestructibleService ) { - $service->destroy(); - } - } - - $this->destroyed = true; - } - - /** - * @param array $wiringFiles A list of PHP files to load wiring information from. - * Each file is loaded using PHP's include mechanism. Each file is expected to - * return an associative array that maps service names to instantiator functions. - */ - public function loadWiringFiles( array $wiringFiles ) { - foreach ( $wiringFiles as $file ) { - // the wiring file is required to return an array of instantiators. - $wiring = require $file; - - Assert::postcondition( - is_array( $wiring ), - "Wiring file $file is expected to return an array!" - ); - - $this->applyWiring( $wiring ); - } - } - - /** - * Registers multiple services (aka a "wiring"). - * - * @param array $serviceInstantiators An associative array mapping service names to - * instantiator functions. - */ - public function applyWiring( array $serviceInstantiators ) { - Assert::parameterElementType( 'callable', $serviceInstantiators, '$serviceInstantiators' ); - - foreach ( $serviceInstantiators as $name => $instantiator ) { - $this->defineService( $name, $instantiator ); - } - } - - /** - * Imports all wiring defined in $container. Wiring defined in $container - * will override any wiring already defined locally. However, already - * existing service instances will be preserved. - * - * @since 1.28 - * - * @param ServiceContainer $container - * @param string[] $skip A list of service names to skip during import - */ - public function importWiring( ServiceContainer $container, $skip = [] ) { - $newInstantiators = array_diff_key( - $container->serviceInstantiators, - array_flip( $skip ) - ); - - $this->serviceInstantiators = array_merge( - $this->serviceInstantiators, - $newInstantiators - ); - } - - /** - * Returns true if a service is defined for $name, that is, if a call to getService( $name ) - * would return a service instance. - * - * @param string $name - * - * @return bool - */ - public function hasService( $name ) { - return isset( $this->serviceInstantiators[$name] ); - } - - /** - * Returns the service instance for $name only if that service has already been instantiated. - * This is intended for situations where services get destroyed/cleaned up, so we can - * avoid creating a service just to destroy it again. - * - * @note This is intended for internal use and for test fixtures. - * Application logic should use getService() instead. - * - * @see getService(). - * - * @param string $name - * - * @return object|null The service instance, or null if the service has not yet been instantiated. - * @throws RuntimeException if $name does not refer to a known service. - */ - public function peekService( $name ) { - if ( !$this->hasService( $name ) ) { - throw new NoSuchServiceException( $name ); - } - - return isset( $this->services[$name] ) ? $this->services[$name] : null; - } - - /** - * @return string[] - */ - public function getServiceNames() { - return array_keys( $this->serviceInstantiators ); - } - - /** - * Define a new service. The service must not be known already. - * - * @see getService(). - * @see replaceService(). - * - * @param string $name The name of the service to register, for use with getService(). - * @param callable $instantiator Callback that returns a service instance. - * Will be called with this MediaWikiServices instance as the only parameter. - * Any extra instantiation parameters provided to the constructor will be - * passed as subsequent parameters when invoking the instantiator. - * - * @throws RuntimeException if there is already a service registered as $name. - */ - public function defineService( $name, callable $instantiator ) { - Assert::parameterType( 'string', $name, '$name' ); - - if ( $this->hasService( $name ) ) { - throw new ServiceAlreadyDefinedException( $name ); - } - - $this->serviceInstantiators[$name] = $instantiator; - } - - /** - * Replace an already defined service. - * - * @see defineService(). - * - * @note This causes any previously instantiated instance of the service to be discarded. - * - * @param string $name The name of the service to register. - * @param callable $instantiator Callback function that returns a service instance. - * Will be called with this MediaWikiServices instance as the only parameter. - * The instantiator must return a service compatible with the originally defined service. - * Any extra instantiation parameters provided to the constructor will be - * passed as subsequent parameters when invoking the instantiator. - * - * @throws RuntimeException if $name is not a known service. - */ - public function redefineService( $name, callable $instantiator ) { - Assert::parameterType( 'string', $name, '$name' ); - - if ( !$this->hasService( $name ) ) { - throw new NoSuchServiceException( $name ); - } - - if ( isset( $this->services[$name] ) ) { - throw new CannotReplaceActiveServiceException( $name ); - } - - $this->serviceInstantiators[$name] = $instantiator; - unset( $this->disabled[$name] ); - } - - /** - * Disables a service. - * - * @note Attempts to call getService() for a disabled service will result - * in a DisabledServiceException. Calling peekService for a disabled service will - * return null. Disabled services are listed by getServiceNames(). A disabled service - * can be enabled again using redefineService(). - * - * @note If the service was already active (that is, instantiated) when getting disabled, - * and the service instance implements DestructibleService, destroy() is called on the - * service instance. - * - * @see redefineService() - * @see resetService() - * - * @param string $name The name of the service to disable. - * - * @throws RuntimeException if $name is not a known service. - */ - public function disableService( $name ) { - $this->resetService( $name ); - - $this->disabled[$name] = true; - } - - /** - * Resets a service by dropping the service instance. - * If the service instances implements DestructibleService, destroy() - * is called on the service instance. - * - * @warning This is generally unsafe! Other services may still retain references - * to the stale service instance, leading to failures and inconsistencies. Subclasses - * may use this method to reset specific services under specific instances, but - * it should not be exposed to application logic. - * - * @note This is declared final so subclasses can not interfere with the expectations - * disableService() has when calling resetService(). - * - * @see redefineService() - * @see disableService(). - * - * @param string $name The name of the service to reset. - * @param bool $destroy Whether the service instance should be destroyed if it exists. - * When set to false, any existing service instance will effectively be detached - * from the container. - * - * @throws RuntimeException if $name is not a known service. - */ - final protected function resetService( $name, $destroy = true ) { - Assert::parameterType( 'string', $name, '$name' ); - - $instance = $this->peekService( $name ); - - if ( $destroy && $instance instanceof DestructibleService ) { - $instance->destroy(); - } - - unset( $this->services[$name] ); - unset( $this->disabled[$name] ); - } - - /** - * Returns a service object of the kind associated with $name. - * Services instances are instantiated lazily, on demand. - * This method may or may not return the same service instance - * when called multiple times with the same $name. - * - * @note Rather than calling this method directly, it is recommended to provide - * getters with more meaningful names and more specific return types, using - * a subclass or wrapper. - * - * @see redefineService(). - * - * @param string $name The service name - * - * @throws NoSuchServiceException if $name is not a known service. - * @throws ContainerDisabledException if this container has already been destroyed. - * @throws ServiceDisabledException if the requested service has been disabled. - * - * @return object The service instance - */ - public function getService( $name ) { - if ( $this->destroyed ) { - throw new ContainerDisabledException(); - } - - if ( isset( $this->disabled[$name] ) ) { - throw new ServiceDisabledException( $name ); - } - - if ( !isset( $this->services[$name] ) ) { - $this->services[$name] = $this->createService( $name ); - } - - return $this->services[$name]; - } - - /** - * @param string $name - * - * @throws InvalidArgumentException if $name is not a known service. - * @return object - */ - private function createService( $name ) { - if ( isset( $this->serviceInstantiators[$name] ) ) { - $service = call_user_func_array( - $this->serviceInstantiators[$name], - array_merge( [ $this ], $this->extraInstantiationParams ) - ); - // NOTE: when adding more wiring logic here, make sure copyWiring() is kept in sync! - } else { - throw new NoSuchServiceException( $name ); - } - - return $service; - } - - /** - * @param string $name - * @return bool Whether the service is disabled - * @since 1.28 - */ - public function isServiceDisabled( $name ) { - return isset( $this->disabled[$name] ); - } -} diff --git a/includes/Services/ServiceDisabledException.php b/includes/Services/ServiceDisabledException.php deleted file mode 100644 index ae15b7cea5..0000000000 --- a/includes/Services/ServiceDisabledException.php +++ /dev/null @@ -1,43 +0,0 @@ -destroy() + * after carefully detaching all relevant resources. + * + * @param SalvageableService $other The object to salvage state from. $other must have the + * exact same type as $this. + */ + public function salvage( SalvageableService $other ); + +} diff --git a/includes/services/ServiceAlreadyDefinedException.php b/includes/services/ServiceAlreadyDefinedException.php new file mode 100644 index 0000000000..c6344d3955 --- /dev/null +++ b/includes/services/ServiceAlreadyDefinedException.php @@ -0,0 +1,45 @@ +extraInstantiationParams = $extraInstantiationParams; + } + + /** + * Destroys all contained service instances that implement the DestructibleService + * interface. This will render all services obtained from this MediaWikiServices + * instance unusable. In particular, this will disable access to the storage backend + * via any of these services. Any future call to getService() will throw an exception. + * + * @see resetGlobalInstance() + */ + public function destroy() { + foreach ( $this->getServiceNames() as $name ) { + $service = $this->peekService( $name ); + if ( $service !== null && $service instanceof DestructibleService ) { + $service->destroy(); + } + } + + $this->destroyed = true; + } + + /** + * @param array $wiringFiles A list of PHP files to load wiring information from. + * Each file is loaded using PHP's include mechanism. Each file is expected to + * return an associative array that maps service names to instantiator functions. + */ + public function loadWiringFiles( array $wiringFiles ) { + foreach ( $wiringFiles as $file ) { + // the wiring file is required to return an array of instantiators. + $wiring = require $file; + + Assert::postcondition( + is_array( $wiring ), + "Wiring file $file is expected to return an array!" + ); + + $this->applyWiring( $wiring ); + } + } + + /** + * Registers multiple services (aka a "wiring"). + * + * @param array $serviceInstantiators An associative array mapping service names to + * instantiator functions. + */ + public function applyWiring( array $serviceInstantiators ) { + Assert::parameterElementType( 'callable', $serviceInstantiators, '$serviceInstantiators' ); + + foreach ( $serviceInstantiators as $name => $instantiator ) { + $this->defineService( $name, $instantiator ); + } + } + + /** + * Imports all wiring defined in $container. Wiring defined in $container + * will override any wiring already defined locally. However, already + * existing service instances will be preserved. + * + * @since 1.28 + * + * @param ServiceContainer $container + * @param string[] $skip A list of service names to skip during import + */ + public function importWiring( ServiceContainer $container, $skip = [] ) { + $newInstantiators = array_diff_key( + $container->serviceInstantiators, + array_flip( $skip ) + ); + + $this->serviceInstantiators = array_merge( + $this->serviceInstantiators, + $newInstantiators + ); + } + + /** + * Returns true if a service is defined for $name, that is, if a call to getService( $name ) + * would return a service instance. + * + * @param string $name + * + * @return bool + */ + public function hasService( $name ) { + return isset( $this->serviceInstantiators[$name] ); + } + + /** + * Returns the service instance for $name only if that service has already been instantiated. + * This is intended for situations where services get destroyed/cleaned up, so we can + * avoid creating a service just to destroy it again. + * + * @note This is intended for internal use and for test fixtures. + * Application logic should use getService() instead. + * + * @see getService(). + * + * @param string $name + * + * @return object|null The service instance, or null if the service has not yet been instantiated. + * @throws RuntimeException if $name does not refer to a known service. + */ + public function peekService( $name ) { + if ( !$this->hasService( $name ) ) { + throw new NoSuchServiceException( $name ); + } + + return isset( $this->services[$name] ) ? $this->services[$name] : null; + } + + /** + * @return string[] + */ + public function getServiceNames() { + return array_keys( $this->serviceInstantiators ); + } + + /** + * Define a new service. The service must not be known already. + * + * @see getService(). + * @see replaceService(). + * + * @param string $name The name of the service to register, for use with getService(). + * @param callable $instantiator Callback that returns a service instance. + * Will be called with this MediaWikiServices instance as the only parameter. + * Any extra instantiation parameters provided to the constructor will be + * passed as subsequent parameters when invoking the instantiator. + * + * @throws RuntimeException if there is already a service registered as $name. + */ + public function defineService( $name, callable $instantiator ) { + Assert::parameterType( 'string', $name, '$name' ); + + if ( $this->hasService( $name ) ) { + throw new ServiceAlreadyDefinedException( $name ); + } + + $this->serviceInstantiators[$name] = $instantiator; + } + + /** + * Replace an already defined service. + * + * @see defineService(). + * + * @note This causes any previously instantiated instance of the service to be discarded. + * + * @param string $name The name of the service to register. + * @param callable $instantiator Callback function that returns a service instance. + * Will be called with this MediaWikiServices instance as the only parameter. + * The instantiator must return a service compatible with the originally defined service. + * Any extra instantiation parameters provided to the constructor will be + * passed as subsequent parameters when invoking the instantiator. + * + * @throws RuntimeException if $name is not a known service. + */ + public function redefineService( $name, callable $instantiator ) { + Assert::parameterType( 'string', $name, '$name' ); + + if ( !$this->hasService( $name ) ) { + throw new NoSuchServiceException( $name ); + } + + if ( isset( $this->services[$name] ) ) { + throw new CannotReplaceActiveServiceException( $name ); + } + + $this->serviceInstantiators[$name] = $instantiator; + unset( $this->disabled[$name] ); + } + + /** + * Disables a service. + * + * @note Attempts to call getService() for a disabled service will result + * in a DisabledServiceException. Calling peekService for a disabled service will + * return null. Disabled services are listed by getServiceNames(). A disabled service + * can be enabled again using redefineService(). + * + * @note If the service was already active (that is, instantiated) when getting disabled, + * and the service instance implements DestructibleService, destroy() is called on the + * service instance. + * + * @see redefineService() + * @see resetService() + * + * @param string $name The name of the service to disable. + * + * @throws RuntimeException if $name is not a known service. + */ + public function disableService( $name ) { + $this->resetService( $name ); + + $this->disabled[$name] = true; + } + + /** + * Resets a service by dropping the service instance. + * If the service instances implements DestructibleService, destroy() + * is called on the service instance. + * + * @warning This is generally unsafe! Other services may still retain references + * to the stale service instance, leading to failures and inconsistencies. Subclasses + * may use this method to reset specific services under specific instances, but + * it should not be exposed to application logic. + * + * @note This is declared final so subclasses can not interfere with the expectations + * disableService() has when calling resetService(). + * + * @see redefineService() + * @see disableService(). + * + * @param string $name The name of the service to reset. + * @param bool $destroy Whether the service instance should be destroyed if it exists. + * When set to false, any existing service instance will effectively be detached + * from the container. + * + * @throws RuntimeException if $name is not a known service. + */ + final protected function resetService( $name, $destroy = true ) { + Assert::parameterType( 'string', $name, '$name' ); + + $instance = $this->peekService( $name ); + + if ( $destroy && $instance instanceof DestructibleService ) { + $instance->destroy(); + } + + unset( $this->services[$name] ); + unset( $this->disabled[$name] ); + } + + /** + * Returns a service object of the kind associated with $name. + * Services instances are instantiated lazily, on demand. + * This method may or may not return the same service instance + * when called multiple times with the same $name. + * + * @note Rather than calling this method directly, it is recommended to provide + * getters with more meaningful names and more specific return types, using + * a subclass or wrapper. + * + * @see redefineService(). + * + * @param string $name The service name + * + * @throws NoSuchServiceException if $name is not a known service. + * @throws ContainerDisabledException if this container has already been destroyed. + * @throws ServiceDisabledException if the requested service has been disabled. + * + * @return object The service instance + */ + public function getService( $name ) { + if ( $this->destroyed ) { + throw new ContainerDisabledException(); + } + + if ( isset( $this->disabled[$name] ) ) { + throw new ServiceDisabledException( $name ); + } + + if ( !isset( $this->services[$name] ) ) { + $this->services[$name] = $this->createService( $name ); + } + + return $this->services[$name]; + } + + /** + * @param string $name + * + * @throws InvalidArgumentException if $name is not a known service. + * @return object + */ + private function createService( $name ) { + if ( isset( $this->serviceInstantiators[$name] ) ) { + $service = call_user_func_array( + $this->serviceInstantiators[$name], + array_merge( [ $this ], $this->extraInstantiationParams ) + ); + // NOTE: when adding more wiring logic here, make sure copyWiring() is kept in sync! + } else { + throw new NoSuchServiceException( $name ); + } + + return $service; + } + + /** + * @param string $name + * @return bool Whether the service is disabled + * @since 1.28 + */ + public function isServiceDisabled( $name ) { + return isset( $this->disabled[$name] ); + } +} diff --git a/includes/services/ServiceDisabledException.php b/includes/services/ServiceDisabledException.php new file mode 100644 index 0000000000..ae15b7cea5 --- /dev/null +++ b/includes/services/ServiceDisabledException.php @@ -0,0 +1,43 @@ +