Skip to content

Commit cbac8ef

Browse files
committed
refactor(policy): auto-discover file appliers from provider registry
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 6c12f77 commit cbac8ef

1 file changed

Lines changed: 70 additions & 20 deletions

File tree

lib/Service/Policy/FilePolicyApplier.php

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,74 +11,124 @@
1111
use OCA\Libresign\Db\File as FileEntity;
1212
use OCA\Libresign\Service\FileService;
1313
use OCA\Libresign\Service\Policy\Provider\DocMdp\FilePolicy\DocMdpFilePolicyApplier;
14+
use OCA\Libresign\Service\Policy\Provider\FilePolicy\Contract\IFilePolicyApplier;
1415
use OCA\Libresign\Service\Policy\Provider\Footer\FilePolicy\FooterFilePolicyApplier;
16+
use OCA\Libresign\Service\Policy\Provider\PolicyProviders;
1517
use OCA\Libresign\Service\Policy\Provider\Signature\FilePolicy\SignatureFlowFilePolicyApplier;
1618
use OCP\IL10N;
1719

1820
class FilePolicyApplier {
19-
private readonly SignatureFlowFilePolicyApplier $signatureFlowApplier;
20-
private readonly DocMdpFilePolicyApplier $docMdpApplier;
21-
private readonly FooterFilePolicyApplier $footerApplier;
21+
/** @var list<IFilePolicyApplier> */
22+
private readonly array $appliers;
2223

2324
public function __construct(
2425
private readonly PolicyService $policyService,
2526
private readonly FileService $fileService,
2627
private readonly IL10N $l10n,
2728
) {
28-
$this->signatureFlowApplier = new SignatureFlowFilePolicyApplier($this->policyService, $this->fileService, $this->l10n);
29-
$this->docMdpApplier = new DocMdpFilePolicyApplier($this->policyService, $this->fileService);
30-
$this->footerApplier = new FooterFilePolicyApplier($this->policyService, $this->fileService, $this->l10n);
29+
$this->appliers = $this->discoverAppliers();
3130
}
3231

3332
/**
3433
* Apply all policies to a freshly built FileEntity before the first insert.
3534
*/
3635
public function applyAll(FileEntity $file, array $data): void {
37-
$this->applySignatureFlow($file, $data);
38-
$this->applyDocMdpLevel($file, $data);
39-
$this->applyFooterPolicy($file, $data);
36+
foreach ($this->appliers as $applier) {
37+
$applier->apply($file, $data);
38+
}
4039
}
4140

4241
/**
4342
* Re-evaluate and persist signature_flow + docmdp on an existing file.
4443
* Use this when updating a file located by UUID.
4544
*/
4645
public function syncCoreFlowPolicies(FileEntity $file, array $data): void {
47-
$this->syncSignatureFlow($file, $data);
48-
$this->syncDocMdpLevel($file, $data);
46+
foreach ($this->appliers as $applier) {
47+
if ($applier->supportsCoreFlowSync()) {
48+
$applier->sync($file, $data);
49+
}
50+
}
4951
}
5052

5153
/**
5254
* Re-evaluate and persist all three policies on an existing file.
5355
* Use this when updating a file located by node ID.
5456
*/
5557
public function syncAllPolicies(FileEntity $file, array $data): void {
56-
$this->syncSignatureFlow($file, $data);
57-
$this->syncDocMdpLevel($file, $data);
58-
$this->syncFooterPolicy($file, $data);
58+
foreach ($this->appliers as $applier) {
59+
$applier->sync($file, $data);
60+
}
5961
}
6062

6163
private function applySignatureFlow(FileEntity $file, array $data): void {
62-
$this->signatureFlowApplier->apply($file, $data);
64+
$this->getApplierByClass(SignatureFlowFilePolicyApplier::class)->apply($file, $data);
6365
}
6466

6567
private function syncSignatureFlow(FileEntity $file, array $data): void {
66-
$this->signatureFlowApplier->sync($file, $data);
68+
$this->getApplierByClass(SignatureFlowFilePolicyApplier::class)->sync($file, $data);
6769
}
6870

6971
private function applyDocMdpLevel(FileEntity $file, array $data): void {
70-
$this->docMdpApplier->apply($file, $data);
72+
$this->getApplierByClass(DocMdpFilePolicyApplier::class)->apply($file, $data);
7173
}
7274

7375
private function syncDocMdpLevel(FileEntity $file, array $data): void {
74-
$this->docMdpApplier->sync($file, $data);
76+
$this->getApplierByClass(DocMdpFilePolicyApplier::class)->sync($file, $data);
7577
}
7678

7779
private function applyFooterPolicy(FileEntity $file, array $data): void {
78-
$this->footerApplier->apply($file, $data);
80+
$this->getApplierByClass(FooterFilePolicyApplier::class)->apply($file, $data);
7981
}
8082

8183
private function syncFooterPolicy(FileEntity $file, array $data): void {
82-
$this->footerApplier->sync($file, $data);
84+
$this->getApplierByClass(FooterFilePolicyApplier::class)->sync($file, $data);
85+
}
86+
87+
/** @return list<IFilePolicyApplier> */
88+
private function discoverAppliers(): array {
89+
$appliers = [];
90+
91+
foreach (PolicyProviders::BY_KEY as $providerClass) {
92+
$applierClass = $this->buildFileApplierClassFromProvider($providerClass);
93+
if ($applierClass === null || !class_exists($applierClass)) {
94+
continue;
95+
}
96+
97+
$instance = new $applierClass($this->policyService, $this->fileService, $this->l10n);
98+
if (!$instance instanceof IFilePolicyApplier) {
99+
continue;
100+
}
101+
102+
$appliers[] = $instance;
103+
}
104+
105+
return $appliers;
106+
}
107+
108+
/** @param class-string $providerClass */
109+
private function buildFileApplierClassFromProvider(string $providerClass): ?string {
110+
$lastSeparator = strrpos($providerClass, '\\');
111+
if ($lastSeparator === false) {
112+
return null;
113+
}
114+
115+
$namespace = substr($providerClass, 0, $lastSeparator);
116+
$shortName = substr($providerClass, $lastSeparator + 1);
117+
$baseName = str_ends_with($shortName, 'Policy')
118+
? substr($shortName, 0, -strlen('Policy'))
119+
: $shortName;
120+
121+
return $namespace . '\\FilePolicy\\' . $baseName . 'FilePolicyApplier';
122+
}
123+
124+
/** @param class-string<IFilePolicyApplier> $class */
125+
private function getApplierByClass(string $class): IFilePolicyApplier {
126+
foreach ($this->appliers as $applier) {
127+
if ($applier instanceof $class) {
128+
return $applier;
129+
}
130+
}
131+
132+
throw new \RuntimeException(sprintf('File policy applier "%s" not registered.', $class));
83133
}
84134
}

0 commit comments

Comments
 (0)