001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.model.control.workflow.server.logic; 018 019import com.echothree.control.user.workflow.common.spec.WorkflowDestinationUniversalSpec; 020import com.echothree.model.control.core.common.ComponentVendors; 021import com.echothree.model.control.core.common.EntityTypes; 022import com.echothree.model.control.core.common.exception.InvalidParameterCountException; 023import com.echothree.model.control.core.server.logic.EntityInstanceLogic; 024import com.echothree.model.control.party.server.logic.PartyLogic; 025import com.echothree.model.control.security.server.logic.SecurityRoleLogic; 026import com.echothree.model.control.selector.server.logic.SelectorLogic; 027import com.echothree.model.control.workflow.common.exception.MissingRequiredWorkflowNameException; 028import com.echothree.model.control.workflow.common.exception.MissingRequiredWorkflowStepNameException; 029import com.echothree.model.control.workflow.common.exception.UnknownDefaultWorkflowDestinationException; 030import com.echothree.model.control.workflow.common.exception.UnknownDestinationWorkflowNameException; 031import com.echothree.model.control.workflow.common.exception.UnknownDestinationWorkflowStepNameException; 032import com.echothree.model.control.workflow.common.exception.UnknownWorkflowDestinationPartyTypeException; 033import com.echothree.model.control.workflow.common.exception.UnknownWorkflowDestinationSecurityRoleException; 034import com.echothree.model.control.workflow.common.exception.UnknownWorkflowDestinationSelectorException; 035import com.echothree.model.control.workflow.common.exception.UnknownWorkflowDestinationStepException; 036import com.echothree.model.control.workflow.common.exception.UnknownWorkflowNameException; 037import com.echothree.model.control.workflow.common.exception.WorkflowMissingSecurityRoleGroupException; 038import com.echothree.model.control.workflow.common.exception.WorkflowMissingSelectorTypeException; 039import com.echothree.model.control.workflow.server.control.WorkflowControl; 040import com.echothree.model.data.party.server.entity.PartyType; 041import com.echothree.model.data.workflow.server.entity.Workflow; 042import com.echothree.model.data.workflow.server.entity.WorkflowDestination; 043import com.echothree.model.data.workflow.server.entity.WorkflowDestinationPartyType; 044import com.echothree.model.data.workflow.server.entity.WorkflowDestinationSecurityRole; 045import com.echothree.model.data.workflow.server.entity.WorkflowDestinationSelector; 046import com.echothree.model.data.workflow.server.entity.WorkflowDestinationStep; 047import com.echothree.model.data.workflow.server.entity.WorkflowStep; 048import com.echothree.util.common.message.ExecutionErrors; 049import com.echothree.util.server.control.BaseLogic; 050import com.echothree.util.server.message.ExecutionErrorAccumulator; 051import com.echothree.util.server.persistence.EntityPermission; 052import com.echothree.util.server.validation.ParameterUtils; 053import java.util.HashMap; 054import java.util.HashSet; 055import java.util.Map; 056import java.util.Set; 057import javax.enterprise.context.ApplicationScoped; 058import javax.enterprise.inject.spi.CDI; 059import javax.inject.Inject; 060 061@ApplicationScoped 062public class WorkflowDestinationLogic 063 extends BaseLogic { 064 065 @Inject 066 WorkflowControl workflowControl; 067 068 @Inject 069 EntityInstanceLogic entityInstanceLogic; 070 071 @Inject 072 PartyLogic partyLogic; 073 074 @Inject 075 SecurityRoleLogic securityRoleLogic; 076 077 @Inject 078 SelectorLogic selectorLogic; 079 080 @Inject 081 WorkflowStepLogic workflowStepLogic; 082 083 protected WorkflowDestinationLogic() { 084 super(); 085 } 086 087 public static WorkflowDestinationLogic getInstance() { 088 return CDI.current().select(WorkflowDestinationLogic.class).get(); 089 } 090 091 public WorkflowDestination getWorkflowDestinationByName(final ExecutionErrorAccumulator eea, final WorkflowStep workflowStep, 092 final String workflowDestinationName, final EntityPermission entityPermission) { 093 var workflowDestination = workflowControl.getWorkflowDestinationByName(workflowStep, workflowDestinationName, 094 entityPermission); 095 096 if(workflowDestination == null) { 097 var workflowStepDetail = workflowStep.getLastDetail(); 098 099 handleExecutionError(UnknownWorkflowNameException.class, eea, ExecutionErrors.UnknownWorkflowDestinationName.name(), 100 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), workflowStepDetail.getWorkflowStepName(), workflowDestinationName); 101 } 102 103 return workflowDestination; 104 } 105 106 public WorkflowDestination getWorkflowDestinationByName(final ExecutionErrorAccumulator eea, final WorkflowStep workflowStep, 107 final String workflowDestinationName) { 108 return getWorkflowDestinationByName(eea, workflowStep, workflowDestinationName, EntityPermission.READ_ONLY); 109 } 110 111 public WorkflowDestination getWorkflowDestinationByNameForUpdate(final ExecutionErrorAccumulator eea, final WorkflowStep workflowStep, 112 final String workflowDestinationName) { 113 return getWorkflowDestinationByName(eea, workflowStep, workflowDestinationName, EntityPermission.READ_WRITE); 114 } 115 116 public WorkflowDestination getWorkflowDestinationByName(final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowStepName, 117 final String workflowDestinationName) { 118 var workflowStep = workflowStepLogic.getWorkflowStepByName(eea, workflow, workflowStepName); 119 WorkflowDestination workflowDestination = null; 120 121 if(eea == null || !eea.hasExecutionErrors()) { 122 workflowDestination = getWorkflowDestinationByName(eea, workflowStep, workflowDestinationName, EntityPermission.READ_ONLY); 123 } 124 125 return workflowDestination; 126 } 127 128 public WorkflowDestination getWorkflowDestinationByName(final ExecutionErrorAccumulator eea, final String workflowName, final String workflowStepName, 129 final String workflowDestinationName) { 130 var workflowStep = workflowStepLogic.getWorkflowStepByName(eea, workflowName, workflowStepName); 131 WorkflowDestination workflowDestination = null; 132 133 if(eea == null || !eea.hasExecutionErrors()) { 134 workflowDestination = getWorkflowDestinationByName(eea, workflowStep, workflowDestinationName, EntityPermission.READ_ONLY); 135 } 136 137 return workflowDestination; 138 } 139 140 public WorkflowDestination getWorkflowDestinationByUniversalSpec(final ExecutionErrorAccumulator eea, final WorkflowDestinationUniversalSpec universalSpec, 141 final boolean allowDefault, final EntityPermission entityPermission) { 142 var workflowName = universalSpec.getWorkflowName(); 143 var workflowStepName = universalSpec.getWorkflowStepName(); 144 var workflowDestinationName = universalSpec.getWorkflowDestinationName(); 145 var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(workflowName, workflowStepName, workflowDestinationName); 146 var possibleEntitySpecs= entityInstanceLogic.countPossibleEntitySpecs(universalSpec); 147 WorkflowDestination workflowDestination = null; 148 149 if(nameParameterCount < 4 && possibleEntitySpecs == 0) { 150 WorkflowStep workflowStep = null; 151 152 if(workflowName != null && workflowStepName != null) { 153 workflowStep = workflowStepLogic.getWorkflowStepByName(eea, workflowName, workflowStepName); 154 } else { 155 if(workflowName != null) { 156 handleExecutionError(MissingRequiredWorkflowNameException.class, eea, ExecutionErrors.MissingRequiredWorkflowName.name()); 157 } 158 159 if(workflowStepName != null) { 160 handleExecutionError(MissingRequiredWorkflowStepNameException.class, eea, ExecutionErrors.MissingRequiredWorkflowStepName.name()); 161 } 162 } 163 164 if(eea == null || !eea.hasExecutionErrors()) { 165 if(workflowDestinationName == null) { 166 if(allowDefault) { 167 workflowDestination = workflowControl.getDefaultWorkflowDestination(workflowStep, entityPermission); 168 169 if(workflowDestination == null) { 170 handleExecutionError(UnknownDefaultWorkflowDestinationException.class, eea, ExecutionErrors.UnknownDefaultWorkflowDestination.name()); 171 } 172 } else { 173 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 174 } 175 } else { 176 workflowDestination = getWorkflowDestinationByName(eea, workflowStep, workflowDestinationName, entityPermission); 177 } 178 } 179 } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) { 180 var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec, 181 ComponentVendors.ECHO_THREE.name(), EntityTypes.WorkflowDestination.name()); 182 183 if(eea == null || !eea.hasExecutionErrors()) { 184 workflowDestination = workflowControl.getWorkflowDestinationByEntityInstance(entityInstance, entityPermission); 185 } 186 } else { 187 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 188 } 189 190 return workflowDestination; 191 } 192 193 public WorkflowDestination getWorkflowDestinationByUniversalSpec(final ExecutionErrorAccumulator eea, final WorkflowDestinationUniversalSpec universalSpec, 194 boolean allowDefault) { 195 return getWorkflowDestinationByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY); 196 } 197 198 public WorkflowDestination getWorkflowDestinationByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final WorkflowDestinationUniversalSpec universalSpec, 199 boolean allowDefault) { 200 return getWorkflowDestinationByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE); 201 } 202 203 public Set<WorkflowStep> getWorkflowDestinationStepsAsSet(final WorkflowDestination workflowDestination) { 204 var workflowDestinationSteps = workflowControl.getWorkflowDestinationStepsByWorkflowDestination(workflowDestination); 205 Set<WorkflowStep> workflowSteps = new HashSet<>(workflowDestinationSteps.size()); 206 207 workflowDestinationSteps.forEach((workflowDestinationStep) -> { 208 workflowSteps.add(workflowDestinationStep.getWorkflowStep()); 209 }); 210 211 return workflowSteps; 212 } 213 214 public Map<String, Set<String>> getWorkflowDestinationsAsMap(final WorkflowDestination workflowDestination) { 215 var workflowDestinationSteps = workflowControl.getWorkflowDestinationStepsByWorkflowDestination(workflowDestination); 216 Map<String, Set<String>> map = new HashMap<>(); 217 218 workflowDestinationSteps.stream().map((workflowDestinationStep) -> workflowDestinationStep.getWorkflowStep().getLastDetail()).forEach((workflowStepDetail) -> { 219 var workflowStepName = workflowStepDetail.getWorkflowStepName(); 220 var workflowName = workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(); 221 222 workflowDestinationMapContainsStep(map, workflowName, workflowStepName, true); 223 }); 224 225 return map; 226 } 227 228 private boolean workflowDestinationMapContainsStep(final Map<String, Set<String>> map, final String workflowName, 229 final String workflowStepName, final boolean addIt) { 230 var workflowSteps = map.get(workflowName); 231 232 if(workflowSteps == null && addIt) { 233 workflowSteps = new HashSet<>(); 234 map.put(workflowName, workflowSteps); 235 } 236 237 var found = workflowSteps != null && workflowSteps.contains(workflowStepName); 238 239 if(!found && addIt) { 240 workflowSteps.add(workflowStepName); 241 } 242 243 return found; 244 } 245 246 public boolean workflowDestinationMapContainsStep(final Map<String, Set<String>> map, final String workflowName, 247 final String workflowStepName) { 248 return workflowDestinationMapContainsStep(map, workflowName, workflowStepName, false); 249 } 250 251 public WorkflowDestinationPartyType getWorkflowDestinationPartyType(final ExecutionErrorAccumulator eea, final WorkflowDestination workflowDestination, 252 final PartyType partyType, final EntityPermission entityPermission) { 253 WorkflowDestinationPartyType workflowDestinationPartyType = null; 254 255 if(eea == null || !eea.hasExecutionErrors()) { 256 workflowDestinationPartyType = workflowControl.getWorkflowDestinationPartyType(workflowDestination, partyType, entityPermission); 257 258 if(workflowDestinationPartyType == null) { 259 var workflowDestinationDetail = workflowDestination.getLastDetail(); 260 var workflowStepDetail = workflowDestinationDetail.getWorkflowStep().getLastDetail(); 261 262 handleExecutionError(UnknownWorkflowDestinationPartyTypeException.class, eea, ExecutionErrors.UnknownWorkflowDestinationPartyType.name(), 263 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), workflowStepDetail.getWorkflowStepName(), 264 workflowDestinationDetail.getWorkflowDestinationName(), partyType.getPartyTypeName()); 265 } 266 } 267 268 return workflowDestinationPartyType; 269 } 270 271 public WorkflowDestinationPartyType getWorkflowDestinationPartyType(final ExecutionErrorAccumulator eea, final WorkflowDestination workflowDestination, 272 final PartyType partyType) { 273 return getWorkflowDestinationPartyType(eea, workflowDestination, partyType, EntityPermission.READ_ONLY); 274 } 275 276 public WorkflowDestinationPartyType getWorkflowDestinationPartyTypeForUpdate(final ExecutionErrorAccumulator eea, final WorkflowDestination workflowDestination, 277 final PartyType partyType) { 278 return getWorkflowDestinationPartyType(eea, workflowDestination, partyType, EntityPermission.READ_WRITE); 279 } 280 281 public WorkflowDestinationPartyType getWorkflowDestinationPartyTypeByName(final ExecutionErrorAccumulator eea, final String workflowName, 282 final String workflowStepName, final String workflowDestinationName, final String partyTypeName, final EntityPermission entityPermission) { 283 var workflowDestination = getWorkflowDestinationByName(eea, workflowName, workflowStepName, workflowDestinationName); 284 var partyType = partyLogic.getPartyTypeByName(eea, partyTypeName); 285 286 return getWorkflowDestinationPartyType(eea, workflowDestination, partyType, entityPermission); 287 } 288 289 public WorkflowDestinationPartyType getWorkflowDestinationPartyTypeByName(final ExecutionErrorAccumulator eea, final String workflowName, 290 final String workflowStepName, final String workflowDestinationName, final String partyTypeName) { 291 return getWorkflowDestinationPartyTypeByName(eea, workflowName, workflowStepName, workflowDestinationName, partyTypeName, 292 EntityPermission.READ_ONLY); 293 } 294 295 296 public WorkflowDestinationPartyType getWorkflowDestinationPartyTypeByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 297 final String workflowStepName, final String workflowDestinationName, final String partyTypeName) { 298 return getWorkflowDestinationPartyTypeByName(eea, workflowName, workflowStepName, workflowDestinationName, partyTypeName, 299 EntityPermission.READ_WRITE); 300 } 301 302 public WorkflowDestinationSecurityRole getWorkflowDestinationSecurityRoleByName(final ExecutionErrorAccumulator eea, final String workflowName, 303 final String workflowStepName, final String workflowDestinationName, final String partyTypeName, final String securityRoleName, 304 final EntityPermission entityPermission) { 305 var workflowDestination = getWorkflowDestinationByName(eea, workflowName, workflowStepName, workflowDestinationName); 306 var partyType = partyLogic.getPartyTypeByName(eea, partyTypeName); 307 WorkflowDestinationSecurityRole workflowDestinationSecurityRole = null; 308 309 if(eea == null || !eea.hasExecutionErrors()) { 310 var securityRoleGroup = workflowDestination.getLastDetail().getWorkflowStep().getLastDetail().getWorkflow().getLastDetail().getSecurityRoleGroup(); 311 312 if(securityRoleGroup != null) { 313 var securityRole = securityRoleLogic.getSecurityRoleByName(eea, securityRoleGroup, securityRoleName); 314 315 if(eea == null || !eea.hasExecutionErrors()) { 316 var workflowDestinationPartyType = getWorkflowDestinationPartyType(eea, workflowDestination, partyType); 317 318 if(eea == null || !eea.hasExecutionErrors()) { 319 workflowDestinationSecurityRole = workflowControl.getWorkflowDestinationSecurityRole(workflowDestinationPartyType, 320 securityRole, entityPermission); 321 322 if(workflowDestinationSecurityRole == null) { 323 var workflowDestinationDetail = workflowDestination.getLastDetail(); 324 var workflowStepDetail = workflowDestinationDetail.getWorkflowStep().getLastDetail(); 325 var securityRoleDetail = securityRole.getLastDetail(); 326 327 handleExecutionError(UnknownWorkflowDestinationSecurityRoleException.class, eea, ExecutionErrors.UnknownWorkflowDestinationSecurityRole.name(), 328 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), 329 workflowStepDetail.getWorkflowStepName(), workflowDestinationDetail.getWorkflowDestinationName(), 330 partyType.getPartyTypeName(), securityRoleDetail.getSecurityRole().getLastDetail().getSecurityRoleName()); 331 } 332 } 333 } 334 } else { 335 var workflowStepDetail = workflowDestination.getLastDetail().getWorkflowStep().getLastDetail(); 336 337 handleExecutionError(WorkflowMissingSecurityRoleGroupException.class, eea, ExecutionErrors.WorkflowMissingSecurityRoleGroup.name(), 338 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName()); 339 } 340 } 341 342 return workflowDestinationSecurityRole; 343 } 344 345 public WorkflowDestinationSecurityRole getWorkflowDestinationSecurityRoleByName(final ExecutionErrorAccumulator eea, final String workflowName, 346 final String workflowStepName, final String workflowDestinationName, final String partyTypeName, final String securityRoleName) { 347 return getWorkflowDestinationSecurityRoleByName(eea, workflowName, workflowStepName, workflowDestinationName, partyTypeName, 348 securityRoleName, EntityPermission.READ_ONLY); 349 } 350 351 352 public WorkflowDestinationSecurityRole getWorkflowDestinationSecurityRoleByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 353 final String workflowStepName, final String workflowDestinationName, final String partyTypeName, final String securityRoleName) { 354 return getWorkflowDestinationSecurityRoleByName(eea, workflowName, workflowStepName, workflowDestinationName, partyTypeName, 355 securityRoleName, EntityPermission.READ_WRITE); 356 } 357 358 public WorkflowDestinationSelector getWorkflowDestinationSelectorByName(final ExecutionErrorAccumulator eea, final String workflowName, 359 final String workflowStepName, final String workflowDestinationName, final String selectorName, 360 final EntityPermission entityPermission) { 361 var workflowDestination = getWorkflowDestinationByName(eea, workflowName, workflowStepName, workflowDestinationName); 362 WorkflowDestinationSelector workflowDestinationSelector = null; 363 364 if(eea == null || !eea.hasExecutionErrors()) { 365 var selectorType = workflowDestination.getLastDetail().getWorkflowStep().getLastDetail().getWorkflow().getLastDetail().getSelectorType(); 366 367 if(selectorType != null) { 368 var selector = selectorLogic.getSelectorByName(eea, selectorType, selectorName); 369 370 if(eea == null || !eea.hasExecutionErrors()) { 371 workflowDestinationSelector = workflowControl.getWorkflowDestinationSelector(workflowDestination, 372 selector, entityPermission); 373 374 if(workflowDestinationSelector == null) { 375 var workflowDestinationDetail = workflowDestination.getLastDetail(); 376 var workflowStepDetail = workflowDestinationDetail.getWorkflowStep().getLastDetail(); 377 var selectorDetail = selector.getLastDetail(); 378 379 handleExecutionError(UnknownWorkflowDestinationSelectorException.class, eea, ExecutionErrors.UnknownWorkflowDestinationSelector.name(), 380 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), 381 workflowStepDetail.getWorkflowStepName(), workflowDestinationDetail.getWorkflowDestinationName(), 382 selectorDetail.getSelector().getLastDetail().getSelectorName()); 383 } 384 } 385 } else { 386 var workflowStepDetail = workflowDestination.getLastDetail().getWorkflowStep().getLastDetail(); 387 388 handleExecutionError(WorkflowMissingSelectorTypeException.class, eea, ExecutionErrors.WorkflowMissingSelectorType.name(), 389 workflowStepDetail.getWorkflow().getLastDetail().getWorkflowName()); 390 } 391 } 392 393 return workflowDestinationSelector; 394 } 395 396 public WorkflowDestinationSelector getWorkflowDestinationSelectorByName(final ExecutionErrorAccumulator eea, final String workflowName, 397 final String workflowStepName, final String workflowDestinationName, final String selectorName) { 398 return getWorkflowDestinationSelectorByName(eea, workflowName, workflowStepName, workflowDestinationName, selectorName, 399 EntityPermission.READ_ONLY); 400 } 401 402 403 public WorkflowDestinationSelector getWorkflowDestinationSelectorByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 404 final String workflowStepName, final String workflowDestinationName, final String selectorName) { 405 return getWorkflowDestinationSelectorByName(eea, workflowName, workflowStepName, workflowDestinationName, selectorName, 406 EntityPermission.READ_WRITE); 407 } 408 409 public WorkflowStep getDestinationWorkflowStep(final ExecutionErrorAccumulator eea, final String destinationWorkflowName, 410 final String destinationWorkflowStepName) { 411 return workflowStepLogic.getWorkflowStepByName( 412 UnknownDestinationWorkflowNameException.class, ExecutionErrors.UnknownDestinationWorkflowName, 413 UnknownDestinationWorkflowStepNameException.class, ExecutionErrors.UnknownDestinationWorkflowStepName, 414 eea, destinationWorkflowName, destinationWorkflowStepName); 415 } 416 417 public WorkflowDestinationStep getWorkflowDestinationStep(final ExecutionErrorAccumulator eea, 418 WorkflowDestination workflowDestination, WorkflowStep destinationWorkflowStep) { 419 var workflowDestinationStep = workflowControl.getWorkflowDestinationStep(workflowDestination, destinationWorkflowStep); 420 421 if(workflowDestinationStep == null) { 422 var workflowDestinationDetail = workflowDestination.getLastDetail(); 423 var destinationWorkflowStepDetail = destinationWorkflowStep.getLastDetail(); 424 425 handleExecutionError(UnknownWorkflowDestinationStepException.class, eea, ExecutionErrors.UnknownWorkflowDestinationStep.name(), 426 workflowDestinationDetail.getWorkflowStep().getLastDetail().getWorkflow().getLastDetail().getWorkflowName(), 427 workflowDestinationDetail.getWorkflowStep().getLastDetail().getWorkflowStepName(), 428 workflowDestinationDetail.getWorkflowDestinationName(), 429 destinationWorkflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), 430 destinationWorkflowStepDetail.getWorkflowStepName()); 431 } 432 433 return workflowDestinationStep; 434 } 435 436 public WorkflowDestinationStep getWorkflowDestinationStepByName(final ExecutionErrorAccumulator eea, 437 final String workflowName, final String workflowStepName, final String workflowDestinationName, 438 final String destinationWorkflowName, final String destinationWorkflowStepName) { 439 var workflowDestination = getWorkflowDestinationByName(eea, workflowName, workflowStepName, workflowDestinationName); 440 var destinationWorkflowStep = getDestinationWorkflowStep(eea, destinationWorkflowName, destinationWorkflowStepName); 441 WorkflowDestinationStep workflowDestinationStep = null; 442 443 if(eea == null || !eea.hasExecutionErrors()) { 444 workflowDestinationStep = getWorkflowDestinationStep(eea, workflowDestination, destinationWorkflowStep); 445 } 446 447 return workflowDestinationStep; 448 } 449 450}