Test Failed
Push — main ( 131025...bf7814 )
by Bingo
10:39 queued 32s
created

isSameMessageEventSubscriptionAlreadyPresent()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
dl 0
loc 26
rs 9.5555
c 1
b 0
f 0
cc 5
nc 3
nop 2
1
<?php
2
3
namespace Jabe\Engine\Impl\Bpmn\Deployer;
4
5
use Jabe\Engine\Delegate\ExpressionInterface;
6
use Jabe\Engine\Impl\{
7
    AbstractDefinitionDeployer,
8
    ProcessEngineLogger
9
};
10
use Jabe\Engine\Impl\Bpmn\Helper\BpmnProperties;
11
use Jabe\Engine\Impl\Bpmn\Parser\{
12
    BpmnParse,
13
    BpmnParser,
14
    BpmnParseLogger,
15
    EventSubscriptionDeclaration
16
};
17
use Jabe\Engine\Impl\Cmd\DeleteJobsCmd;
18
use Jabe\Engine\Impl\Context\Context;
19
use Jabe\Engine\Impl\Core\Model\{
20
    Properties,
21
    PropertyMapKey
22
};
23
use Jabe\Engine\Impl\Db\EntityManager\DbEntityManager;
24
use Jabe\Engine\Impl\El\ExpressionManager;
25
use Jabe\Engine\Impl\Event\EventType;
26
use Jabe\Engine\Impl\JobExecutor\{
27
    JobDeclaration,
28
    TimerDeclarationImpl,
29
    TimerStartEventJobHandler
30
};
31
use Jabe\Engine\Impl\Persistence\Deploy\DeployerInterface;
32
use Jabe\Engine\Impl\Persistence\Deploy\Cache\DeploymentCache;
33
use Jabe\Engine\Impl\Persistence\Entity\{
34
    DeploymentEntity,
35
    EventSubscriptionEntity,
36
    EventSubscriptionManager,
37
    IdentityLinkEntity,
38
    JobDefinitionEntity,
39
    JobDefinitionManager,
40
    JobEntity,
41
    JobManager,
42
    ProcessDefinitionEntity,
43
    ProcessDefinitionManager,
44
    ResourceEntity
45
};
46
use Jabe\Engine\Impl\Pvm\Runtime\LegacyBehavior;
47
use Jabe\Engine\Management\JobDefinitionInterface;
48
use Jabe\Engine\Repository\ProcessDefinitionInterface;
49
use Jabe\Engine\Task\IdentityLinkType;
50
51
class BpmnDeployer extends AbstractDefinitionDeployer
52
{
53
    //public static BpmnParseLogger LOG = ProcessEngineLogger.BPMN_PARSE_LOGGER;
54
55
    public const BPMN_RESOURCE_SUFFIXES = [ "bpmn20.xml", "bpmn" ];
56
57
    protected static $JOB_DECLARATIONS_PROPERTY;
58
59
    protected $expressionManager;
60
    protected $bpmnParser;
61
62
    /** <!> DON'T KEEP DEPLOYMENT-SPECIFIC STATE <!> **/
63
64
    public function __construct()
65
    {
66
        if (self::$JOB_DECLARATIONS_PROPERTY === null) {
67
            self::$JOB_DECLARATIONS_PROPERTY = new PropertyMapKey("JOB_DECLARATIONS_PROPERTY");
68
        }
69
    }
70
71
    protected function getResourcesSuffixes(): array
72
    {
73
        return self::BPMN_RESOURCE_SUFFIXES;
74
    }
75
76
    protected function transformDefinitions(DeploymentEntity $deployment, ResourceEntity $resource, Properties $properties): array
77
    {
78
        $bytes = $resource->getBytes();
79
80
        $inputStream = tmpfile();
81
        fwrite($inputStream, $bytes);
0 ignored issues
show
Bug introduced by
It seems like $bytes can also be of type null; however, parameter $data of fwrite() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

81
        fwrite($inputStream, /** @scrutinizer ignore-type */ $bytes);
Loading history...
82
83
        $bpmnParse = $this->bpmnParser
84
            ->createParse()
85
            ->sourceInputStream($inputStream)
86
            ->deployment($deployment)
87
            ->name($resource->getName());
88
89
        if (!$deployment->isValidatingSchema()) {
90
            $bpmnParse->setSchemaResource(null);
91
        }
92
93
        $bpmnParse->execute();
94
95
        if (!$this->properties->contains(self::$JOB_DECLARATIONS_PROPERTY)) {
0 ignored issues
show
Bug Best Practice introduced by
The property properties does not exist on Jabe\Engine\Impl\Bpmn\Deployer\BpmnDeployer. Did you maybe forget to declare it?
Loading history...
96
            $this->propertie->set(self::$JOB_DECLARATIONS_PROPERTY, []);
0 ignored issues
show
Bug Best Practice introduced by
The property propertie does not exist on Jabe\Engine\Impl\Bpmn\Deployer\BpmnDeployer. Did you maybe forget to declare it?
Loading history...
97
        }
98
        $this->propertie->set(self::$JOB_DECLARATIONS_PROPERTY, array_merge($this->properties->get(self::$JOB_DECLARATIONS_PROPERTY), $bpmnParse->getJobDeclarations()));
99
100
        return $bpmnParse->getProcessDefinitions();
101
    }
102
103
    protected function findDefinitionByDeploymentAndKey(string $deploymentId, string $definitionKey): ProcessDefinitionEntity
104
    {
105
        return $this->getProcessDefinitionManager()->findProcessDefinitionByDeploymentAndKey($deploymentId, $definitionKey);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getProcess...mentId, $definitionKey) could return the type null which is incompatible with the type-hinted return Jabe\Engine\Impl\Persist...ProcessDefinitionEntity. Consider adding an additional type-check to rule them out.
Loading history...
106
    }
107
108
    protected function findLatestDefinitionByKeyAndTenantId(string $definitionKey, string $tenantId): ProcessDefinitionEntity
109
    {
110
        return $this->getProcessDefinitionManager()->findLatestProcessDefinitionByKeyAndTenantId($definitionKey, $tenantId);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getProcess...finitionKey, $tenantId) could return the type null which is incompatible with the type-hinted return Jabe\Engine\Impl\Persist...ProcessDefinitionEntity. Consider adding an additional type-check to rule them out.
Loading history...
111
    }
112
113
    protected function persistDefinition(ProcessDefinitionEntity $definition): void
114
    {
115
        getProcessDefinitionManager()->insertProcessDefinition($definition);
0 ignored issues
show
Bug introduced by
The function getProcessDefinitionManager was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
        /** @scrutinizer ignore-call */ 
116
        getProcessDefinitionManager()->insertProcessDefinition($definition);
Loading history...
116
    }
117
118
    protected function addDefinitionToDeploymentCache(DeploymentCache $deploymentCache, ProcessDefinitionEntity $definition): void
119
    {
120
        $deploymentCache->addProcessDefinition($definition);
121
    }
122
123
    protected function definitionAddedToDeploymentCache(DeploymentEntity $deployment, ProcessDefinitionEntity $definition, Properties $properties): void
124
    {
125
        $props = $properties->get(self::$JOB_DECLARATIONS_PROPERTY);
126
        $declarations = [];
127
        if (array_key_exists($definition->getKey(), $props)) {
128
            $declarations = $props[$definition->getKey()];
129
        }
130
131
        $this->updateJobDeclarations($declarations, $definition, $deployment->isNew());
132
133
        $latestDefinition = $this->findLatestDefinitionByKeyAndTenantId($definition->getKey(), $definition->getTenantId());
0 ignored issues
show
Bug introduced by
It seems like $definition->getTenantId() can also be of type null; however, parameter $tenantId of Jabe\Engine\Impl\Bpmn\De...itionByKeyAndTenantId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

133
        $latestDefinition = $this->findLatestDefinitionByKeyAndTenantId($definition->getKey(), /** @scrutinizer ignore-type */ $definition->getTenantId());
Loading history...
134
135
        if ($deployment->isNew()) {
136
            $this->adjustStartEventSubscriptions($definition, $latestDefinition);
137
        }
138
139
        // add "authorizations"
140
        $this->addAuthorizations($definition);
141
    }
142
143
    protected function persistedDefinitionLoaded(DeploymentEntity $deployment, ProcessDefinitionEntity $definition, ProcessDefinitionEntity $persistedDefinition): void
144
    {
145
        $definition->setSuspensionState($persistedDefinition->getSuspensionState());
146
    }
147
148
    protected function handlePersistedDefinition(ProcessDefinitionEntity $definition, ?ProcessDefinitionEntity $persistedDefinition, DeploymentEntity $deployment, Properties $properties): void
149
    {
150
        //check if persisted definition is not null, since the process definition can be deleted by the user
151
        //in such cases we don't want to handle them
152
        //we can't do this in the parent method, since other siblings want to handle them like {@link DecisionDefinitionDeployer}
153
        if ($persistedDefinition !== null) {
154
            parent::handlePersistedDefinition($definition, $persistedDefinition, $deployment, $properties);
155
        }
156
    }
157
158
    protected function updateJobDeclarations(array $jobDeclarations, ProcessDefinitionEntity $processDefinition, bool $isNewDeployment): void
159
    {
160
        if (empty($jobDeclarations)) {
161
            return;
162
        }
163
164
        $jobDefinitionManager = $this->getJobDefinitionManager();
0 ignored issues
show
Unused Code introduced by
The assignment to $jobDefinitionManager is dead and can be removed.
Loading history...
165
166
        if ($isNewDeployment) {
167
            // create new job definitions:
168
            foreach ($jobDeclarations as $jobDeclaration) {
169
                $this->createJobDefinition($processDefinition, $jobDeclaration);
170
            }
171
        }/* else {
172
            // query all job definitions and update the declarations with their Ids
173
            List<JobDefinitionEntity> existingDefinitions = jobDefinitionManager->findByProcessDefinitionId(processDefinition->getId());
174
175
            LegacyBehavior.migrateMultiInstanceJobDefinitions(processDefinition, existingDefinitions);
176
177
            for (JobDeclaration<?, ?> jobDeclaration : jobDeclarations) {
178
                boolean jobDefinitionExists = false;
179
                for (JobDefinition jobDefinitionEntity : existingDefinitions) {
180
181
                    // <!> Assumption: there can be only one job definition per activity and type
182
                    if (jobDeclaration->getActivityId().equals(jobDefinitionEntity->getActivityId()) &&
183
                        jobDeclaration->getJobHandlerType().equals(jobDefinitionEntity->getJobType())) {
184
                        jobDeclaration.setJobDefinitionId(jobDefinitionEntity->getId());
185
                        jobDefinitionExists = true;
186
                        break;
187
                    }
188
                }
189
190
                if (!jobDefinitionExists) {
191
                    // not found: create new definition
192
                    createJobDefinition(processDefinition, jobDeclaration);
193
                }
194
195
            }
196
        }*/
197
    }
198
199
    protected function createJobDefinition(ProcessDefinitionInterface $processDefinition, JobDeclaration $jobDeclaration): void
200
    {
201
        $jobDefinitionManager = $this->getJobDefinitionManager();
202
203
        $jobDefinitionEntity = new JobDefinitionEntity($jobDeclaration);
204
        $jobDefinitionEntity->setProcessDefinitionId($processDefinition->getId());
205
        $jobDefinitionEntity->setProcessDefinitionKey($processDefinition->getKey());
206
        $jobDefinitionEntity->setTenantId($processDefinition->getTenantId());
207
        $jobDefinitionManager->insert($jobDefinitionEntity);
208
        $jobDeclaration->setJobDefinitionId($jobDefinitionEntity->getId());
0 ignored issues
show
Bug introduced by
It seems like $jobDefinitionEntity->getId() can also be of type null; however, parameter $jobDefinitionId of Jabe\Engine\Impl\JobExec...n::setJobDefinitionId() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

208
        $jobDeclaration->setJobDefinitionId(/** @scrutinizer ignore-type */ $jobDefinitionEntity->getId());
Loading history...
209
    }
210
211
    /**
212
     * adjust all event subscriptions responsible to start process instances
213
     * (timer start event, message start event). The default behavior is to remove the old
214
     * subscriptions and add new ones for the new deployed process definitions.
215
     */
216
    protected function adjustStartEventSubscriptions(ProcessDefinitionEntity $newLatestProcessDefinition, ProcessDefinitionEntity $oldLatestProcessDefinition): void
217
    {
218
        $this->removeObsoleteTimers($newLatestProcessDefinition);
219
        $this->addTimerDeclarations($newLatestProcessDefinition);
220
221
        $this->removeObsoleteEventSubscriptions($newLatestProcessDefinition, $oldLatestProcessDefinition);
222
        $this->addEventSubscriptions($newLatestProcessDefinition);
223
    }
224
225
    protected function addTimerDeclarations(ProcessDefinitionEntity $processDefinition): void
226
    {
227
        $timerDeclarations = $processDefinition->getProperty(BpmnParse::PROPERTYNAME_START_TIMER);
228
        if ($timerDeclarations !== null) {
229
            foreach ($timerDeclarations as $timerDeclaration) {
230
                $deploymentId = $processDefinition->getDeploymentId();
231
                $timerDeclaration->createStartTimerInstance($deploymentId);
232
            }
233
        }
234
    }
235
236
    protected function removeObsoleteTimers(ProcessDefinitionEntity $processDefinition): void
237
    {
238
        $jobsToDelete = $this->getJobManager()
239
            ->findJobsByConfiguration(TimerStartEventJobHandler::TYPE, $processDefinition->getKey(), $processDefinition->getTenantId());
240
241
        foreach ($jobsToDelete as $job) {
242
            (new DeleteJobsCmd($job->getId()))->execute(Context::getCommandContext());
0 ignored issues
show
Bug introduced by
It seems like Jabe\Engine\Impl\Context...xt::getCommandContext() can also be of type null; however, parameter $commandContext of Jabe\Engine\Impl\Cmd\DeleteJobsCmd::execute() does only seem to accept Jabe\Engine\Impl\Interceptor\CommandContext, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

242
            (new DeleteJobsCmd($job->getId()))->execute(/** @scrutinizer ignore-type */ Context::getCommandContext());
Loading history...
243
        }
244
    }
245
246
    protected function removeObsoleteEventSubscriptions(ProcessDefinitionEntity $processDefinition, ProcessDefinitionEntity $latestProcessDefinition): void
0 ignored issues
show
Unused Code introduced by
The parameter $processDefinition is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

246
    protected function removeObsoleteEventSubscriptions(/** @scrutinizer ignore-unused */ ProcessDefinitionEntity $processDefinition, ProcessDefinitionEntity $latestProcessDefinition): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
247
    {
248
        // remove all subscriptions for the previous version
249
        if ($latestProcessDefinition !== null) {
250
            $eventSubscriptionManager = $this->getEventSubscriptionManager();
251
252
            $subscriptionsToDelete = [];
253
254
            $messageEventSubscriptions = $eventSubscriptionManager->findEventSubscriptionsByConfiguration(EventType::message()->name(), $latestProcessDefinition->getId());
255
            $subscriptionsToDelete = array_merge($subscriptionsToDelete, $messageEventSubscriptions);
256
257
            $signalEventSubscriptions = $eventSubscriptionManager->findEventSubscriptionsByConfiguration(EventType::signal()->name(), $latestProcessDefinition->getId());
258
            $subscriptionsToDelete = array_merge($subscriptionsToDelete, $signalEventSubscriptions);
259
260
            $conditionalEventSubscriptions = $eventSubscriptionManager->findEventSubscriptionsByConfiguration(EventType::conditional()->name(), $latestProcessDefinition->getId());
261
            $subscriptionsToDelete = array_merge($subscriptionsToDelete, $conditionalEventSubscriptions);
262
263
            foreach ($subscriptionsToDelete as $eventSubscriptionEntity) {
264
                $eventSubscriptionEntity->delete();
265
            }
266
        }
267
    }
268
269
    public function addEventSubscriptions(ProcessDefinitionEntity $processDefinition): void
270
    {
271
        $eventDefinitions = $processDefinition->getProperties()->get(BpmnProperties::eventSubscriptionDeclarations());
272
        foreach (array_values($eventDefinitions) as $eventDefinition) {
273
            $this->addEventSubscription($processDefinition, $eventDefinition);
274
        }
275
    }
276
277
    protected function addEventSubscription(ProcessDefinitionEntity $processDefinition, EventSubscriptionDeclaration $eventDefinition): void
278
    {
279
        if ($eventDefinition->isStartEvent()) {
280
            $eventType = $eventDefinition->getEventType();
281
282
            if ($eventType == EventType::message()->name()) {
283
                $this->addMessageStartEventSubscription($eventDefinition, $processDefinition);
284
            } elseif ($eventType == EventType::signal()->name()) {
285
                $this->addSignalStartEventSubscription($eventDefinition, $processDefinition);
286
            } elseif ($eventType == EventType::conditional()->name()) {
287
                $this->addConditionalStartEventSubscription($eventDefinition, $processDefinition);
288
            }
289
        }
290
    }
291
292
    protected function addMessageStartEventSubscription(EventSubscriptionDeclaration $messageEventDefinition, ProcessDefinitionEntity $processDefinition): void
293
    {
294
        $tenantId = $processDefinition->getTenantId();
295
296
        if ($this->isSameMessageEventSubscriptionAlreadyPresent($messageEventDefinition, $tenantId)) {
0 ignored issues
show
Bug introduced by
It seems like $tenantId can also be of type null; however, parameter $tenantId of Jabe\Engine\Impl\Bpmn\De...riptionAlreadyPresent() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

296
        if ($this->isSameMessageEventSubscriptionAlreadyPresent($messageEventDefinition, /** @scrutinizer ignore-type */ $tenantId)) {
Loading history...
297
            //throw LOG.messageEventSubscriptionWithSameNameExists(processDefinition->getResourceName(), messageEventDefinition->getUnresolvedEventName());
298
            throw new \Exception("messageEventSubscriptionWithSameNameExists");
299
        }
300
301
        $newSubscription = $messageEventDefinition->createSubscriptionForStartEvent($processDefinition);
302
        $newSubscription->insert();
303
    }
304
305
    protected function isSameMessageEventSubscriptionAlreadyPresent(EventSubscriptionDeclaration $eventSubscription, string $tenantId): bool
306
    {
307
        // look for subscriptions for the same name in db:
308
        $subscriptionsForSameMessageName = $this->getEventSubscriptionManager()
309
            ->findEventSubscriptionsByNameAndTenantId(EventType::message()->name(), $eventSubscription->getUnresolvedEventName(), $tenantId);
310
311
        // also look for subscriptions created in the session:
312
        $cachedSubscriptions = $this->getDbEntityManager()->getCachedEntitiesByType(EventSubscriptionEntity::class);
313
314
        foreach ($cachedSubscriptions as $cachedSubscription) {
315
            if (
316
                $eventSubscription->getUnresolvedEventName() == $cachedSubscription->getEventName()
317
                && $this->hasTenantId($cachedSubscription, $tenantId)
318
                && !in_array($cachedSubscription, $subscriptionsForSameMessageName)
319
            ) {
320
                $subscriptionsForSameMessageName[] = $cachedSubscription;
321
            }
322
        }
323
324
        // remove subscriptions deleted in the same command
325
        $subscriptionsForSameMessageName = $this->getDbEntityManager()->pruneDeletedEntities($subscriptionsForSameMessageName);
326
327
        // remove subscriptions for different type of event (i.e. remove intermediate message event subscriptions)
328
        $subscriptionsForSameMessageName = $this->filterSubscriptionsOfDifferentType($eventSubscription, $subscriptionsForSameMessageName);
329
330
        return !empty($subscriptionsForSameMessageName);
331
    }
332
333
    protected function hasTenantId(EventSubscriptionEntity $cachedSubscription, ?string $tenantId): bool
334
    {
335
        if ($tenantId === null) {
336
            return $cachedSubscription->getTenantId() === null;
337
        } else {
338
            return $tenantId == $cachedSubscription->getTenantId();
339
        }
340
    }
341
342
    /**
343
     * It is possible to deploy a process containing a start and intermediate
344
     * message event that wait for the same message or to have two processes, one
345
     * with a message start event and the other one with a message intermediate
346
     * event, that subscribe for the same message. Therefore we have to find out
347
     * if there are subscriptions for the other type of event and remove those.
348
     *
349
     * @param eventSubscription
350
     * @param subscriptionsForSameMessageName
351
     */
352
    protected function filterSubscriptionsOfDifferentType(EventSubscriptionDeclaration $eventSubscription, array $subscriptionsForSameMessageName): array
353
    {
354
        $filteredSubscriptions = $subscriptionsForSameMessageName ;
355
356
        foreach ($subscriptionsForSameMessageName as $subscriptionEntity) {
357
            if ($this->isSubscriptionOfDifferentTypeAsDeclaration($subscriptionEntity, $eventSubscription)) {
358
                foreach ($filteredSubscriptions as $key => $value) {
359
                    if ($value == $subscriptionEntity) {
360
                        unset($filteredSubscriptions[$subscriptionEntity]);
361
                    }
362
                }
363
            }
364
        }
365
366
        return $filteredSubscriptions;
367
    }
368
369
    protected function isSubscriptionOfDifferentTypeAsDeclaration(EventSubscriptionEntity $subscriptionEntity, EventSubscriptionDeclaration $declaration): bool
370
    {
371
        return ($declaration->isStartEvent() && $this->isSubscriptionForIntermediateEvent($subscriptionEntity))
372
            || (!$declaration->isStartEvent() && $this->isSubscriptionForStartEvent($subscriptionEntity));
373
    }
374
375
    protected function isSubscriptionForStartEvent(EventSubscriptionEntity $subscriptionEntity): bool
376
    {
377
        return $subscriptionEntity->getExecutionId() === null;
378
    }
379
380
    protected function isSubscriptionForIntermediateEvent(EventSubscriptionEntity $subscriptionEntity): bool
381
    {
382
        return $subscriptionEntity->getExecutionId() !== null;
383
    }
384
385
    protected function addSignalStartEventSubscription(EventSubscriptionDeclaration $signalEventDefinition, ProcessDefinitionEntity $processDefinition): void
386
    {
387
        $newSubscription = $signalEventDefinition->createSubscriptionForStartEvent($processDefinition);
388
        $newSubscription->insert();
389
    }
390
391
    protected function addConditionalStartEventSubscription(EventSubscriptionDeclaration $conditionalEventDefinition, ProcessDefinitionEntity $processDefinition): void
392
    {
393
        $newSubscription = $conditionalEventDefinition->createSubscriptionForStartEvent($processDefinition);
394
        $newSubscription->insert();
395
    }
396
397
    protected function addAuthorizationsFromIterator(array $exprSet, ProcessDefinitionEntity $processDefinition, string $exprType): void
398
    {
399
        if (!empty($exprSet)) {
400
            foreach ($exprSet as $expr) {
401
                $identityLink = new IdentityLinkEntity();
402
                $identityLink->setProcessDef($processDefinition);
403
                if ($exprType == ExprType::USER) {
404
                    $identityLink->setUserId(strval($expr));
405
                } elseif ($exprType == ExprType::GROUP) {
406
                    $identityLink->setGroupId(strval($expr));
407
                }
408
                $identityLink->setType(IdentityLinkType::CANDIDATE);
409
                $identityLink->setTenantId($processDefinition->getTenantId());
410
                $identityLink->insert();
411
            }
412
        }
413
    }
414
415
    protected function addAuthorizations(ProcessDefinitionEntity $processDefinition): void
416
    {
417
        $this->addAuthorizationsFromIterator($processDefinition->getCandidateStarterUserIdExpressions(), $processDefinition, ExprType::USER);
418
        $this->addAuthorizationsFromIterator($processDefinition->getCandidateStarterGroupIdExpressions(), $processDefinition, ExprType::GROUP);
419
    }
420
421
    // context ///////////////////////////////////////////////////////////////////////////////////////////
422
423
    protected function getDbEntityManager(): DbEntityManager
424
    {
425
        return $this->getCommandContext()->getDbEntityManager();
426
    }
427
428
    protected function getJobManager(): JobManager
429
    {
430
        return $this->getCommandContext()->getJobManager();
431
    }
432
433
    protected function getJobDefinitionManager(): JobDefinitionManager
434
    {
435
        return $this->getCommandContext()->getJobDefinitionManager();
436
    }
437
438
    protected function getEventSubscriptionManager(): EventSubscriptionManager
439
    {
440
        return $this->getCommandContext()->getEventSubscriptionManager();
441
    }
442
443
    protected function getProcessDefinitionManager(): ProcessDefinitionManager
444
    {
445
        return $this->getCommandContext()->getProcessDefinitionManager();
446
    }
447
448
    // getters/setters ///////////////////////////////////////////////////////////////////////////////////
449
450
    public function getExpressionManager(): ExpressionManager
451
    {
452
        return $this->expressionManager;
453
    }
454
455
    public function setExpressionManager(ExpressionManager $expressionManager): void
456
    {
457
        $this->expressionManager = $expressionManager;
458
    }
459
460
    public function getBpmnParser(): BpmnParser
461
    {
462
        return $this->bpmnParser;
463
    }
464
465
    public function setBpmnParser(BpmnParser $bpmnParser): void
466
    {
467
        $this->bpmnParser = $bpmnParser;
468
    }
469
}
470