]> source.dussan.org Git - nextcloud-server.git/commitdiff
Type the service registration 25359/head
authorChristoph Wurst <christoph@winzerhof-wurst.at>
Thu, 28 Jan 2021 13:08:38 +0000 (14:08 +0100)
committerChristoph Wurst <christoph@winzerhof-wurst.at>
Wed, 10 Feb 2021 08:44:24 +0000 (09:44 +0100)
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
15 files changed:
lib/composer/composer/autoload_classmap.php
lib/composer/composer/autoload_static.php
lib/private/AppFramework/Bootstrap/ARegistration.php [new file with mode: 0644]
lib/private/AppFramework/Bootstrap/EventListenerRegistration.php [new file with mode: 0644]
lib/private/AppFramework/Bootstrap/ParameterRegistration.php [new file with mode: 0644]
lib/private/AppFramework/Bootstrap/RegistrationContext.php
lib/private/AppFramework/Bootstrap/ServiceAliasRegistration.php [new file with mode: 0644]
lib/private/AppFramework/Bootstrap/ServiceFactoryRegistration.php [new file with mode: 0644]
lib/private/AppFramework/Bootstrap/ServiceRegistration.php [new file with mode: 0644]
lib/private/Files/Template/TemplateManager.php
lib/private/Http/WellKnown/RequestManager.php
lib/private/Search/SearchComposer.php
lib/private/legacy/OC_App.php
lib/public/AppFramework/Bootstrap/IRegistrationContext.php
tests/lib/Http/WellKnown/RequestManagerTest.php

index bf770d488144644f1a7842a23b7fd82964501a30..c0728ce9f8e7f68d99f95a5a93147951657fa49b 100644 (file)
@@ -584,10 +584,16 @@ return array(
     'OC\\AllConfig' => $baseDir . '/lib/private/AllConfig.php',
     'OC\\AppConfig' => $baseDir . '/lib/private/AppConfig.php',
     'OC\\AppFramework\\App' => $baseDir . '/lib/private/AppFramework/App.php',
+    'OC\\AppFramework\\Bootstrap\\ARegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/ARegistration.php',
     'OC\\AppFramework\\Bootstrap\\BootContext' => $baseDir . '/lib/private/AppFramework/Bootstrap/BootContext.php',
     'OC\\AppFramework\\Bootstrap\\Coordinator' => $baseDir . '/lib/private/AppFramework/Bootstrap/Coordinator.php',
+    'OC\\AppFramework\\Bootstrap\\EventListenerRegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/EventListenerRegistration.php',
     'OC\\AppFramework\\Bootstrap\\FunctionInjector' => $baseDir . '/lib/private/AppFramework/Bootstrap/FunctionInjector.php',
+    'OC\\AppFramework\\Bootstrap\\ParameterRegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/ParameterRegistration.php',
     'OC\\AppFramework\\Bootstrap\\RegistrationContext' => $baseDir . '/lib/private/AppFramework/Bootstrap/RegistrationContext.php',
+    'OC\\AppFramework\\Bootstrap\\ServiceAliasRegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/ServiceAliasRegistration.php',
+    'OC\\AppFramework\\Bootstrap\\ServiceFactoryRegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/ServiceFactoryRegistration.php',
+    'OC\\AppFramework\\Bootstrap\\ServiceRegistration' => $baseDir . '/lib/private/AppFramework/Bootstrap/ServiceRegistration.php',
     'OC\\AppFramework\\DependencyInjection\\DIContainer' => $baseDir . '/lib/private/AppFramework/DependencyInjection/DIContainer.php',
     'OC\\AppFramework\\Http' => $baseDir . '/lib/private/AppFramework/Http.php',
     'OC\\AppFramework\\Http\\Dispatcher' => $baseDir . '/lib/private/AppFramework/Http/Dispatcher.php',
index 4fa5b2b282d55f176b37b54b96a067b3ad55106c..f55941501b94a486f6d3b01eaf27e6d187340f08 100644 (file)
@@ -613,10 +613,16 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OC\\AllConfig' => __DIR__ . '/../../..' . '/lib/private/AllConfig.php',
         'OC\\AppConfig' => __DIR__ . '/../../..' . '/lib/private/AppConfig.php',
         'OC\\AppFramework\\App' => __DIR__ . '/../../..' . '/lib/private/AppFramework/App.php',
+        'OC\\AppFramework\\Bootstrap\\ARegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/ARegistration.php',
         'OC\\AppFramework\\Bootstrap\\BootContext' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/BootContext.php',
         'OC\\AppFramework\\Bootstrap\\Coordinator' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/Coordinator.php',
+        'OC\\AppFramework\\Bootstrap\\EventListenerRegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/EventListenerRegistration.php',
         'OC\\AppFramework\\Bootstrap\\FunctionInjector' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/FunctionInjector.php',
+        'OC\\AppFramework\\Bootstrap\\ParameterRegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/ParameterRegistration.php',
         'OC\\AppFramework\\Bootstrap\\RegistrationContext' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/RegistrationContext.php',
+        'OC\\AppFramework\\Bootstrap\\ServiceAliasRegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/ServiceAliasRegistration.php',
+        'OC\\AppFramework\\Bootstrap\\ServiceFactoryRegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/ServiceFactoryRegistration.php',
+        'OC\\AppFramework\\Bootstrap\\ServiceRegistration' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Bootstrap/ServiceRegistration.php',
         'OC\\AppFramework\\DependencyInjection\\DIContainer' => __DIR__ . '/../../..' . '/lib/private/AppFramework/DependencyInjection/DIContainer.php',
         'OC\\AppFramework\\Http' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Http.php',
         'OC\\AppFramework\\Http\\Dispatcher' => __DIR__ . '/../../..' . '/lib/private/AppFramework/Http/Dispatcher.php',
diff --git a/lib/private/AppFramework/Bootstrap/ARegistration.php b/lib/private/AppFramework/Bootstrap/ARegistration.php
new file mode 100644 (file)
index 0000000..1dde102
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ */
+abstract class ARegistration {
+
+       /** @var string */
+       private $appId;
+
+       public function __construct(string $appId) {
+               $this->appId = $appId;
+       }
+
+       /**
+        * @return string
+        */
+       public function getAppId(): string {
+               return $this->appId;
+       }
+}
diff --git a/lib/private/AppFramework/Bootstrap/EventListenerRegistration.php b/lib/private/AppFramework/Bootstrap/EventListenerRegistration.php
new file mode 100644 (file)
index 0000000..1781646
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ * @template-extends ServiceRegistration<\OCP\EventDispatcher\IEventListener>
+ */
+class EventListenerRegistration extends ServiceRegistration {
+
+       /** @var string */
+       private $event;
+
+       /** @var int */
+       private $priority;
+
+       public function __construct(string $appId,
+                                                               string $event,
+                                                               string $service,
+                                                               int $priority) {
+               parent::__construct($appId, $service);
+               $this->event = $event;
+               $this->priority = $priority;
+       }
+
+       /**
+        * @return string
+        */
+       public function getEvent(): string {
+               return $this->event;
+       }
+
+       /**
+        * @return int
+        */
+       public function getPriority(): int {
+               return $this->priority;
+       }
+}
diff --git a/lib/private/AppFramework/Bootstrap/ParameterRegistration.php b/lib/private/AppFramework/Bootstrap/ParameterRegistration.php
new file mode 100644 (file)
index 0000000..2e31d70
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ */
+final class ParameterRegistration extends ARegistration {
+
+       /** @var string */
+       private $name;
+
+       /** @var mixed */
+       private $value;
+
+       public function __construct(string $appId,
+                                                               string $name,
+                                                               $value) {
+               parent::__construct($appId);
+               $this->name = $name;
+               $this->value = $value;
+       }
+
+       public function getName(): string {
+               return $this->name;
+       }
+
+       /**
+        * @return mixed
+        */
+       public function getValue() {
+               return $this->value;
+       }
+}
index d2dc365d8350b8b3ac7cb5a9171f0ed07a65837f..619e4f55011f5cbf83c1866bc06ff2c0a4c97796 100644 (file)
@@ -34,50 +34,58 @@ use Closure;
 use OC\Support\CrashReport\Registry;
 use OCP\AppFramework\App;
 use OCP\AppFramework\Bootstrap\IRegistrationContext;
+use OCP\AppFramework\Middleware;
+use OCP\Authentication\IAlternativeLogin;
+use OCP\Capabilities\ICapability;
 use OCP\Dashboard\IManager;
+use OCP\Dashboard\IWidget;
 use OCP\EventDispatcher\IEventDispatcher;
+use OCP\Files\Template\ICustomTemplateProvider;
+use OCP\Http\WellKnown\IHandler;
 use OCP\ILogger;
+use OCP\Search\IProvider;
+use OCP\Support\CrashReport\IReporter;
 use Throwable;
 
 class RegistrationContext {
 
-       /** @var array[] */
+       /** @var ServiceRegistration<ICapability>[] */
        private $capabilities = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<IReporter>[] */
        private $crashReporters = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<IWidget>[] */
        private $dashboardPanels = [];
 
-       /** @var array[] */
+       /** @var ServiceFactoryRegistration[] */
        private $services = [];
 
-       /** @var array[] */
+       /** @var ServiceAliasRegistration[] */
        private $aliases = [];
 
-       /** @var array[] */
+       /** @var ParameterRegistration[] */
        private $parameters = [];
 
-       /** @var array[] */
+       /** @var EventListenerRegistration[] */
        private $eventListeners = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<Middleware>[] */
        private $middlewares = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<IProvider>[] */
        private $searchProviders = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<IAlternativeLogin>[] */
        private $alternativeLogins = [];
 
        /** @var array[] */
        private $initialStates = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<IHandler>[] */
        private $wellKnownHandlers = [];
 
-       /** @var array[] */
+       /** @var ServiceRegistration<ICustomTemplateProvider>[] */
        private $templateProviders = [];
 
        /** @var ILogger */
@@ -199,80 +207,56 @@ class RegistrationContext {
                };
        }
 
+       /**
+        * @psalm-param class-string<ICapability> $capability
+        */
        public function registerCapability(string $appId, string $capability): void {
-               $this->capabilities[] = [
-                       'appId' => $appId,
-                       'capability' => $capability
-               ];
+               $this->capabilities[] = new ServiceRegistration($appId, $capability);
        }
 
+       /**
+        * @psalm-param class-string<IReporter> $capability
+        */
        public function registerCrashReporter(string $appId, string $reporterClass): void {
-               $this->crashReporters[] = [
-                       'appId' => $appId,
-                       'class' => $reporterClass,
-               ];
+               $this->crashReporters[] = new ServiceRegistration($appId, $reporterClass);
        }
 
+       /**
+        * @psalm-param class-string<IWidget> $capability
+        */
        public function registerDashboardPanel(string $appId, string $panelClass): void {
-               $this->dashboardPanels[] = [
-                       'appId' => $appId,
-                       'class' => $panelClass
-               ];
+               $this->dashboardPanels[] = new ServiceRegistration($appId, $panelClass);
        }
 
        public function registerService(string $appId, string $name, callable $factory, bool $shared = true): void {
-               $this->services[] = [
-                       "appId" => $appId,
-                       "name" => $name,
-                       "factory" => $factory,
-                       "shared" => $shared,
-               ];
+               $this->services[] = new ServiceFactoryRegistration($appId, $name, $factory, $shared);
        }
 
        public function registerServiceAlias(string $appId, string $alias, string $target): void {
-               $this->aliases[] = [
-                       "appId" => $appId,
-                       "alias" => $alias,
-                       "target" => $target,
-               ];
+               $this->aliases[] = new ServiceAliasRegistration($appId, $alias, $target);
        }
 
        public function registerParameter(string $appId, string $name, $value): void {
-               $this->parameters[] = [
-                       "appId" => $appId,
-                       "name" => $name,
-                       "value" => $value,
-               ];
+               $this->parameters[] = new ParameterRegistration($appId, $name, $value);
        }
 
        public function registerEventListener(string $appId, string $event, string $listener, int $priority = 0): void {
-               $this->eventListeners[] = [
-                       "appId" => $appId,
-                       "event" => $event,
-                       "listener" => $listener,
-                       "priority" => $priority,
-               ];
+               $this->eventListeners[] = new EventListenerRegistration($appId, $event, $listener, $priority);
        }
 
+       /**
+        * @psalm-param class-string<Middleware> $class
+        */
        public function registerMiddleware(string $appId, string $class): void {
-               $this->middlewares[] = [
-                       "appId" => $appId,
-                       "class" => $class,
-               ];
+               $this->middlewares[] = new ServiceRegistration($appId, $class);
        }
 
        public function registerSearchProvider(string $appId, string $class) {
-               $this->searchProviders[] = [
-                       'appId' => $appId,
-                       'class' => $class,
-               ];
+               $this->searchProviders[] = new ServiceRegistration($appId, $class);
        }
 
        public function registerAlternativeLogin(string $appId, string $class): void {
-               $this->alternativeLogins[] = [
-                       'appId' => $appId,
-                       'class' => $class,
-               ];
+               $this->alternativeLogins[] = new ServiceRegistration($appId, $class);
        }
 
        public function registerInitialState(string $appId, string $class): void {
@@ -283,10 +267,7 @@ class RegistrationContext {
        }
 
        public function registerWellKnown(string $appId, string $class): void {
-               $this->wellKnownHandlers[] = [
-                       'appId' => $appId,
-                       'class' => $class,
-               ];
+               $this->wellKnownHandlers[] = new ServiceRegistration($appId, $class);
        }
 
        public function registerTemplateProvider(string $appId, string $class): void {
@@ -302,11 +283,11 @@ class RegistrationContext {
        public function delegateCapabilityRegistrations(array $apps): void {
                while (($registration = array_shift($this->capabilities)) !== null) {
                        try {
-                               $apps[$registration['appId']]
+                               $apps[$registration->getAppId()]
                                        ->getContainer()
-                                       ->registerCapability($registration['capability']);
+                                       ->registerCapability($registration->getService());
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during capability registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -321,9 +302,9 @@ class RegistrationContext {
        public function delegateCrashReporterRegistrations(array $apps, Registry $registry): void {
                while (($registration = array_shift($this->crashReporters)) !== null) {
                        try {
-                               $registry->registerLazy($registration['class']);
+                               $registry->registerLazy($registration->getService());
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during crash reporter registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -338,9 +319,9 @@ class RegistrationContext {
        public function delegateDashboardPanelRegistrations(array $apps, IManager $dashboardManager): void {
                while (($panel = array_shift($this->dashboardPanels)) !== null) {
                        try {
-                               $dashboardManager->lazyRegisterWidget($panel['class']);
+                               $dashboardManager->lazyRegisterWidget($panel->getService());
                        } catch (Throwable $e) {
-                               $appId = $panel['appId'];
+                               $appId = $panel->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during dashboard registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -352,20 +333,13 @@ class RegistrationContext {
        public function delegateEventListenerRegistrations(IEventDispatcher $eventDispatcher): void {
                while (($registration = array_shift($this->eventListeners)) !== null) {
                        try {
-                               if (isset($registration['priority'])) {
-                                       $eventDispatcher->addServiceListener(
-                                               $registration['event'],
-                                               $registration['listener'],
-                                               $registration['priority']
-                                       );
-                               } else {
-                                       $eventDispatcher->addServiceListener(
-                                               $registration['event'],
-                                               $registration['listener']
-                                       );
-                               }
+                               $eventDispatcher->addServiceListener(
+                                       $registration->getEvent(),
+                                       $registration->getService(),
+                                       $registration->getPriority()
+                               );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during event listener registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -383,15 +357,15 @@ class RegistrationContext {
                                /**
                                 * Register the service and convert the callable into a \Closure if necessary
                                 */
-                               $apps[$registration['appId']]
+                               $apps[$registration->getAppId()]
                                        ->getContainer()
                                        ->registerService(
-                                               $registration['name'],
-                                               Closure::fromCallable($registration['factory']),
-                                               $registration['shared'] ?? true
+                                               $registration->getName(),
+                                               Closure::fromCallable($registration->getFactory()),
+                                               $registration->isShared()
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during service registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -401,14 +375,14 @@ class RegistrationContext {
 
                foreach ($this->aliases as $registration) {
                        try {
-                               $apps[$registration['appId']]
+                               $apps[$registration->getAppId()]
                                        ->getContainer()
                                        ->registerAlias(
-                                               $registration['alias'],
-                                               $registration['target']
+                                               $registration->getAlias(),
+                                               $registration->getTarget()
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during service alias registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -418,14 +392,14 @@ class RegistrationContext {
 
                foreach ($this->parameters as $registration) {
                        try {
-                               $apps[$registration['appId']]
+                               $apps[$registration->getAppId()]
                                        ->getContainer()
                                        ->registerParameter(
-                                               $registration['name'],
-                                               $registration['value']
+                                               $registration->getName(),
+                                               $registration->getValue()
                                        );
                        } catch (Throwable $e) {
-                               $appId = $registration['appId'];
+                               $appId = $registration->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during service alias registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -440,11 +414,11 @@ class RegistrationContext {
        public function delegateMiddlewareRegistrations(array $apps): void {
                while (($middleware = array_shift($this->middlewares)) !== null) {
                        try {
-                               $apps[$middleware['appId']]
+                               $apps[$middleware->getAppId()]
                                        ->getContainer()
-                                       ->registerMiddleWare($middleware['class']);
+                                       ->registerMiddleWare($middleware->getService());
                        } catch (Throwable $e) {
-                               $appId = $middleware['appId'];
+                               $appId = $middleware->getAppId();
                                $this->logger->logException($e, [
                                        'message' => "Error during capability registration of $appId: " . $e->getMessage(),
                                        'level' => ILogger::ERROR,
@@ -454,14 +428,14 @@ class RegistrationContext {
        }
 
        /**
-        * @return array[]
+        * @return ServiceRegistration<IProvider>[]
         */
        public function getSearchProviders(): array {
                return $this->searchProviders;
        }
 
        /**
-        * @return array[]
+        * @return ServiceRegistration<IAlternativeLogin>[]
         */
        public function getAlternativeLogins(): array {
                return $this->alternativeLogins;
@@ -475,12 +449,15 @@ class RegistrationContext {
        }
 
        /**
-        * @return array[]
+        * @return ServiceRegistration<IHandler>[]
         */
        public function getWellKnownHandlers(): array {
                return $this->wellKnownHandlers;
        }
 
+       /**
+        * @return ServiceRegistration<ICustomTemplateProvider>[]
+        */
        public function getTemplateProviders(): array {
                return $this->templateProviders;
        }
diff --git a/lib/private/AppFramework/Bootstrap/ServiceAliasRegistration.php b/lib/private/AppFramework/Bootstrap/ServiceAliasRegistration.php
new file mode 100644 (file)
index 0000000..0482317
--- /dev/null
@@ -0,0 +1,70 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ */
+class ServiceAliasRegistration extends ARegistration {
+
+       /**
+        * @var string
+        * @psalm-var string|class-string
+        */
+       private $alias;
+
+       /**
+        * @var string
+        * @psalm-var string|class-string
+        */
+       private $target;
+
+       /**
+        * @psalm-param string|class-string $alias
+        * @paslm-param string|class-string $target
+        */
+       public function __construct(string $appId,
+                                                               string $alias,
+                                                               string $target) {
+               parent::__construct($appId);
+               $this->alias = $alias;
+               $this->target = $target;
+       }
+
+       /**
+        * @psalm-return string|class-string
+        */
+       public function getAlias(): string {
+               return $this->alias;
+       }
+
+       /**
+        * @psalm-return string|class-string
+        */
+       public function getTarget(): string {
+               return $this->target;
+       }
+}
diff --git a/lib/private/AppFramework/Bootstrap/ServiceFactoryRegistration.php b/lib/private/AppFramework/Bootstrap/ServiceFactoryRegistration.php
new file mode 100644 (file)
index 0000000..4776c5d
--- /dev/null
@@ -0,0 +1,72 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ */
+class ServiceFactoryRegistration extends ARegistration {
+
+       /**
+        * @var string
+        * @psalm-var string|class-string
+        */
+       private $name;
+
+       /**
+        * @var callable
+        * @psalm-var callable(\Psr\Container\ContainerInterface): mixed
+        */
+       private $factory;
+
+       /** @var bool */
+       private $shared;
+
+       public function __construct(string $appId,
+                                                               string $alias,
+                                                               callable $target,
+                                                               bool $shared) {
+               parent::__construct($appId);
+               $this->name = $alias;
+               $this->factory = $target;
+               $this->shared = $shared;
+       }
+
+       public function getName(): string {
+               return $this->name;
+       }
+
+       /**
+        * @psalm-return callable(\Psr\Container\ContainerInterface): mixed
+        */
+       public function getFactory(): callable {
+               return $this->factory;
+       }
+
+       public function isShared(): bool {
+               return $this->shared;
+       }
+}
diff --git a/lib/private/AppFramework/Bootstrap/ServiceRegistration.php b/lib/private/AppFramework/Bootstrap/ServiceRegistration.php
new file mode 100644 (file)
index 0000000..83ffe01
--- /dev/null
@@ -0,0 +1,53 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * @copyright 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @author 2021 Christoph Wurst <christoph@winzerhof-wurst.at>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace OC\AppFramework\Bootstrap;
+
+/**
+ * @psalm-immutable
+ * @template T
+ */
+class ServiceRegistration extends ARegistration {
+       /**
+        * @var string
+        * @psalm-var class-string<T>
+        */
+       private $service;
+
+       /**
+        * @psalm-param class-string<T> $service
+        */
+       public function __construct(string $appId, string $service) {
+               parent::__construct($appId);
+               $this->service = $service;
+       }
+
+       /**
+        * @psalm-return class-string<T>
+        */
+       public function getService(): string {
+               return $this->service;
+       }
+}
index 44e1b10fa357bd8497f84e3af0c11f72c15c93cd..33d42bc9c42e6dbe68c49c59a9efb23baafe3aa0 100644 (file)
@@ -109,7 +109,8 @@ class TemplateManager implements ITemplateManager {
 
                $this->providers = [];
                foreach ($context->getTemplateProviders() as $provider) {
-                       $this->providers[$provider['class']] = $this->serverContainer->get($provider['class']);
+                       $class = $provider->getService();
+                       $this->providers[$class] = $this->serverContainer->get($class);
                }
                return $this->providers;
        }
index 5993a9b36e090670341db067f1dd4a0009222d47..052e2d38ea7a46077c95c3572720d36656f67724 100644 (file)
@@ -27,6 +27,7 @@ declare(strict_types=1);
 namespace OC\Http\WellKnown;
 
 use OC\AppFramework\Bootstrap\Coordinator;
+use OC\AppFramework\Bootstrap\ServiceRegistration;
 use OCP\AppFramework\QueryException;
 use OCP\Http\WellKnown\IHandler;
 use OCP\Http\WellKnown\IRequestContext;
@@ -99,8 +100,9 @@ class RequestManager {
                $this->logger->debug(count($registrations) . " well known handlers registered");
 
                return array_filter(
-                       array_map(function (array $registration) {
-                               $class = $registration['class'];
+                       array_map(function (ServiceRegistration $registration) {
+                               /** @var ServiceRegistration<IHandler> $registration */
+                               $class = $registration->getService();
 
                                try {
                                        $handler = $this->container->get($class);
@@ -115,6 +117,7 @@ class RequestManager {
                                } catch (QueryException $e) {
                                        $this->logger->error("Could not load well known handler $class", [
                                                'exception' => $e,
+                                               'app' => $registration->getAppId(),
                                        ]);
 
                                        return null;
index 5290c2ac3c154d3e2a22bbacfde900b49da58e9d..09355f3aa0e9134a67ece1c28ffe08fb42f66ad0 100644 (file)
@@ -96,13 +96,14 @@ class SearchComposer {
                foreach ($registrations as $registration) {
                        try {
                                /** @var IProvider $provider */
-                               $provider = $this->container->query($registration['class']);
+                               $provider = $this->container->query($registration->getService());
                                $this->providers[$provider->getId()] = $provider;
                        } catch (QueryException $e) {
                                // Log an continue. We can be fault tolerant here.
                                $this->logger->logException($e, [
                                        'message' => 'Could not load search provider dynamically: ' . $e->getMessage(),
                                        'level' => ILogger::ERROR,
+                                       'app' => $registration->getAppId(),
                                ]);
                        }
                }
index a64b13f1e2c8bc3faf056bad62831be816d03c7d..530291002bbc577f95a2b6c549f69dbb5bde4c83 100644 (file)
@@ -698,11 +698,11 @@ class OC_App {
                $bootstrapCoordinator = \OC::$server->query(Coordinator::class);
 
                foreach ($bootstrapCoordinator->getRegistrationContext()->getAlternativeLogins() as $registration) {
-                       if (!in_array(IAlternativeLogin::class, class_implements($registration['class']), true)) {
+                       if (!in_array(IAlternativeLogin::class, class_implements($registration->getService()), true)) {
                                \OC::$server->getLogger()->error('Alternative login option {option} does not implement {interface} and is therefore ignored.', [
-                                       'option' => $registration['class'],
+                                       'option' => $registration->getService(),
                                        'interface' => IAlternativeLogin::class,
-                                       'app' => $registration['app'],
+                                       'app' => $registration->getAppId(),
                                ]);
                                continue;
                        }
index 8bc21a545f6d0dc1cd400557a15679a93e5f7f44..a53a4d2a6e4ef6f6d66893aff77cdcb18855a043 100644 (file)
@@ -30,6 +30,7 @@ declare(strict_types=1);
 namespace OCP\AppFramework\Bootstrap;
 
 use OCP\AppFramework\IAppContainer;
+use OCP\Capabilities\ICapability;
 use OCP\EventDispatcher\IEventDispatcher;
 use OCP\Files\Template\ICustomTemplateProvider;
 use OCP\IContainer;
@@ -44,6 +45,7 @@ interface IRegistrationContext {
 
        /**
         * @param string $capability
+        * @psalm-param class-string<ICapability> $capability
         * @see IAppContainer::registerCapability
         *
         * @since 20.0.0
index b947df494967bc154a0ad5323cfb66565238f2a7..1fa92804cfa0f001a5ed3460ae325a48acb1fe45 100644 (file)
@@ -27,6 +27,7 @@ namespace Test\Http\WellKnown;
 
 use OC\AppFramework\Bootstrap\Coordinator;
 use OC\AppFramework\Bootstrap\RegistrationContext;
+use OC\AppFramework\Bootstrap\ServiceRegistration;
 use OC\Http\WellKnown\RequestManager;
 use OCP\AppFramework\QueryException;
 use OCP\Http\WellKnown\IHandler;
@@ -102,9 +103,7 @@ class RequestManagerTest extends TestCase {
                $registrationContext->expects(self::once())
                        ->method('getWellKnownHandlers')
                        ->willReturn([
-                               [
-                                       'class' => get_class($handler),
-                               ],
+                               new ServiceRegistration('test', get_class($handler)),
                        ]);
                $this->container->expects(self::once())
                        ->method('get')
@@ -129,9 +128,7 @@ class RequestManagerTest extends TestCase {
                $registrationContext->expects(self::once())
                        ->method('getWellKnownHandlers')
                        ->willReturn([
-                               [
-                                       'class' => get_class($handler),
-                               ],
+                               new ServiceRegistration('test', get_class($handler)),
                        ]);
                $this->container->expects(self::once())
                        ->method('get')
@@ -159,9 +156,7 @@ class RequestManagerTest extends TestCase {
                $registrationContext->expects(self::once())
                        ->method('getWellKnownHandlers')
                        ->willReturn([
-                               [
-                                       'class' => get_class($handler),
-                               ],
+                               new ServiceRegistration('test', get_class($handler)),
                        ]);
                $this->container->expects(self::once())
                        ->method('get')