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.WorkflowEntranceUniversalSpec; 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.UnknownDefaultWorkflowEntranceException; 029import com.echothree.model.control.workflow.common.exception.UnknownEntranceWorkflowNameException; 030import com.echothree.model.control.workflow.common.exception.UnknownEntranceWorkflowStepNameException; 031import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntranceNameException; 032import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntrancePartyTypeException; 033import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntranceSecurityRoleException; 034import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntranceSelectorException; 035import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntranceStepException; 036import com.echothree.model.control.workflow.common.exception.WorkflowMissingSecurityRoleGroupException; 037import com.echothree.model.control.workflow.common.exception.WorkflowMissingSelectorTypeException; 038import com.echothree.model.control.workflow.server.control.WorkflowControl; 039import com.echothree.model.data.party.server.entity.PartyType; 040import com.echothree.model.data.workflow.server.entity.Workflow; 041import com.echothree.model.data.workflow.server.entity.WorkflowEntrance; 042import com.echothree.model.data.workflow.server.entity.WorkflowEntrancePartyType; 043import com.echothree.model.data.workflow.server.entity.WorkflowEntranceSecurityRole; 044import com.echothree.model.data.workflow.server.entity.WorkflowEntranceSelector; 045import com.echothree.model.data.workflow.server.entity.WorkflowEntranceStep; 046import com.echothree.model.data.workflow.server.entity.WorkflowStep; 047import com.echothree.util.common.exception.BaseException; 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 javax.enterprise.context.ApplicationScoped; 054import javax.enterprise.inject.spi.CDI; 055import javax.inject.Inject; 056 057@ApplicationScoped 058public class WorkflowEntranceLogic 059 extends BaseLogic { 060 061 @Inject 062 WorkflowControl workflowControl; 063 064 @Inject 065 EntityInstanceLogic entityInstanceLogic; 066 067 @Inject 068 PartyLogic partyLogic; 069 070 @Inject 071 SecurityRoleLogic securityRoleLogic; 072 073 @Inject 074 SelectorLogic selectorLogic; 075 076 @Inject 077 WorkflowLogic workflowLogic; 078 079 @Inject 080 WorkflowStepLogic workflowStepLogic; 081 082 protected WorkflowEntranceLogic() { 083 super(); 084 } 085 086 public static WorkflowEntranceLogic getInstance() { 087 return CDI.current().select(WorkflowEntranceLogic.class).get(); 088 } 089 090 public WorkflowEntrance getWorkflowEntranceByName(final Class<? extends BaseException> unknownWorkflowException, final ExecutionErrors unknownWorkflowExecutionError, 091 final Class<? extends BaseException> unknownWorkflowEntranceException, final ExecutionErrors unknownWorkflowEntranceExecutionError, 092 final ExecutionErrorAccumulator eea, final String workflowName, final String workflowEntranceName) { 093 var workflow = workflowLogic.getWorkflowByName(unknownWorkflowException, unknownWorkflowExecutionError, 094 eea, workflowName, EntityPermission.READ_ONLY); 095 WorkflowEntrance workflowEntrance = null; 096 097 if(eea == null || !eea.hasExecutionErrors()) { 098 workflowEntrance = getWorkflowEntranceByName(unknownWorkflowEntranceException, unknownWorkflowEntranceExecutionError, eea, 099 workflow, workflowEntranceName); 100 } 101 102 return workflowEntrance; 103 } 104 105 public WorkflowEntrance getWorkflowEntranceByName(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError, 106 final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName, EntityPermission entityPermission) { 107 var workflowEntrance = workflowControl.getWorkflowEntranceByName(workflow, workflowEntranceName, entityPermission); 108 109 if(workflowEntrance == null) { 110 handleExecutionError(unknownException, eea, unknownExecutionError.name(), workflow.getLastDetail().getWorkflowName(), 111 workflowEntranceName); 112 } 113 114 return workflowEntrance; 115 } 116 117 public WorkflowEntrance getWorkflowEntranceByName(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError, 118 final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName) { 119 return getWorkflowEntranceByName(unknownException, unknownExecutionError, eea, workflow, workflowEntranceName, EntityPermission.READ_ONLY); 120 } 121 122 public WorkflowEntrance getWorkflowEntranceByNameForUpdate(final Class<? extends BaseException> unknownException, final ExecutionErrors unknownExecutionError, 123 final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName) { 124 return getWorkflowEntranceByName(unknownException, unknownExecutionError, eea, workflow, workflowEntranceName, EntityPermission.READ_WRITE); 125 } 126 127 public WorkflowEntrance getWorkflowEntranceByName(final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName, 128 final EntityPermission entityPermission) { 129 return getWorkflowEntranceByName(UnknownWorkflowEntranceNameException.class, ExecutionErrors.UnknownWorkflowEntranceName, 130 eea, workflow, workflowEntranceName, entityPermission); 131 } 132 133 public WorkflowEntrance getWorkflowEntranceByName(final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName) { 134 return getWorkflowEntranceByName(UnknownWorkflowEntranceNameException.class, ExecutionErrors.UnknownWorkflowEntranceName, 135 eea, workflow, workflowEntranceName); 136 } 137 138 public WorkflowEntrance getWorkflowEntranceByNameForUpdate(final ExecutionErrorAccumulator eea, final Workflow workflow, final String workflowEntranceName) { 139 return getWorkflowEntranceByNameForUpdate(UnknownWorkflowEntranceNameException.class, ExecutionErrors.UnknownWorkflowEntranceName, 140 eea, workflow, workflowEntranceName); 141 } 142 143 public WorkflowEntrance getWorkflowEntranceByName(final ExecutionErrorAccumulator eea, final String workflowName, final String workflowEntranceName, 144 final EntityPermission entityPermission) { 145 var workflow = workflowLogic.getWorkflowByName(eea, workflowName); 146 WorkflowEntrance workflowEntrance = null; 147 148 if(eea == null || !eea.hasExecutionErrors()) { 149 workflowEntrance = getWorkflowEntranceByName(UnknownWorkflowEntranceNameException.class, ExecutionErrors.UnknownWorkflowEntranceName, 150 eea, workflow, workflowEntranceName, entityPermission); 151 } 152 153 return workflowEntrance; 154 } 155 156 public WorkflowEntrance getWorkflowEntranceByName(final ExecutionErrorAccumulator eea, final String workflowName, final String workflowEntranceName) { 157 return getWorkflowEntranceByName(eea, workflowName, workflowEntranceName, EntityPermission.READ_ONLY); 158 } 159 160 public WorkflowEntrance getWorkflowEntranceByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, final String workflowEntranceName) { 161 return getWorkflowEntranceByName(eea, workflowName, workflowEntranceName, EntityPermission.READ_WRITE); 162 } 163 164 public WorkflowEntrance getWorkflowEntranceByUniversalSpec(final ExecutionErrorAccumulator eea, final WorkflowEntranceUniversalSpec universalSpec, 165 final boolean allowDefault, final EntityPermission entityPermission) { 166 var workflowName = universalSpec.getWorkflowName(); 167 var workflowEntranceName = universalSpec.getWorkflowEntranceName(); 168 var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(workflowName, workflowEntranceName); 169 var possibleEntitySpecs= entityInstanceLogic.countPossibleEntitySpecs(universalSpec); 170 WorkflowEntrance workflowEntrance = null; 171 172 if(nameParameterCount < 3 && possibleEntitySpecs == 0) { 173 Workflow workflow = null; 174 175 if(workflowName != null) { 176 workflow = workflowLogic.getWorkflowByName(eea, workflowName); 177 } else { 178 handleExecutionError(MissingRequiredWorkflowNameException.class, eea, ExecutionErrors.MissingRequiredWorkflowName.name()); 179 } 180 181 if(eea == null || !eea.hasExecutionErrors()) { 182 if(workflowEntranceName == null) { 183 if(allowDefault) { 184 workflowEntrance = workflowControl.getDefaultWorkflowEntrance(workflow, entityPermission); 185 186 if(workflowEntrance == null) { 187 handleExecutionError(UnknownDefaultWorkflowEntranceException.class, eea, ExecutionErrors.UnknownDefaultWorkflowEntrance.name()); 188 } 189 } else { 190 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 191 } 192 } else { 193 workflowEntrance = getWorkflowEntranceByName(eea, workflow, workflowEntranceName, entityPermission); 194 } 195 } 196 } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) { 197 var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec, 198 ComponentVendors.ECHO_THREE.name(), EntityTypes.WorkflowEntrance.name()); 199 200 if(eea == null || !eea.hasExecutionErrors()) { 201 workflowEntrance = workflowControl.getWorkflowEntranceByEntityInstance(entityInstance, entityPermission); 202 } 203 } else { 204 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 205 } 206 207 return workflowEntrance; 208 } 209 210 public WorkflowEntrance getWorkflowEntranceByUniversalSpec(final ExecutionErrorAccumulator eea, final WorkflowEntranceUniversalSpec universalSpec, 211 boolean allowDefault) { 212 return getWorkflowEntranceByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY); 213 } 214 215 public WorkflowEntrance getWorkflowEntranceByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final WorkflowEntranceUniversalSpec universalSpec, 216 boolean allowDefault) { 217 return getWorkflowEntranceByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE); 218 } 219 220 public WorkflowEntrancePartyType getWorkflowEntrancePartyType(final ExecutionErrorAccumulator eea, final WorkflowEntrance workflowEntrance, 221 final PartyType partyType, final EntityPermission entityPermission) { 222 WorkflowEntrancePartyType workflowEntrancePartyType = null; 223 224 if(eea == null || !eea.hasExecutionErrors()) { 225 workflowEntrancePartyType = workflowControl.getWorkflowEntrancePartyType(workflowEntrance, partyType, entityPermission); 226 227 if(workflowEntrancePartyType == null) { 228 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 229 230 handleExecutionError(UnknownWorkflowEntrancePartyTypeException.class, eea, ExecutionErrors.UnknownWorkflowEntrancePartyType.name(), 231 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName(), 232 workflowEntranceDetail.getWorkflowEntranceName(), partyType.getPartyTypeName()); 233 } 234 } 235 236 return workflowEntrancePartyType; 237 } 238 239 public WorkflowEntrancePartyType getWorkflowEntrancePartyType(final ExecutionErrorAccumulator eea, final WorkflowEntrance workflowEntrance, 240 final PartyType partyType) { 241 return getWorkflowEntrancePartyType(eea, workflowEntrance, partyType, EntityPermission.READ_ONLY); 242 } 243 244 public WorkflowEntrancePartyType getWorkflowEntrancePartyTypeForUpdate(final ExecutionErrorAccumulator eea, final WorkflowEntrance workflowEntrance, 245 final PartyType partyType) { 246 return getWorkflowEntrancePartyType(eea, workflowEntrance, partyType, EntityPermission.READ_WRITE); 247 } 248 249 public WorkflowEntrancePartyType getWorkflowEntrancePartyTypeByName(final ExecutionErrorAccumulator eea, final String workflowName, 250 final String workflowEntranceName, final String partyTypeName, final EntityPermission entityPermission) { 251 var workflowEntrance = getWorkflowEntranceByName(eea, workflowName, workflowEntranceName); 252 var partyType = partyLogic.getPartyTypeByName(eea, partyTypeName); 253 254 return getWorkflowEntrancePartyType(eea, workflowEntrance, partyType, entityPermission); 255 } 256 257 public WorkflowEntrancePartyType getWorkflowEntrancePartyTypeByName(final ExecutionErrorAccumulator eea, final String workflowName, 258 final String workflowEntranceName, final String partyTypeName) { 259 return getWorkflowEntrancePartyTypeByName(eea, workflowName, workflowEntranceName, partyTypeName, 260 EntityPermission.READ_ONLY); 261 } 262 263 264 public WorkflowEntrancePartyType getWorkflowEntrancePartyTypeByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 265 final String workflowEntranceName, final String partyTypeName) { 266 return getWorkflowEntrancePartyTypeByName(eea, workflowName, workflowEntranceName, partyTypeName, 267 EntityPermission.READ_WRITE); 268 } 269 270 public WorkflowEntranceSecurityRole getWorkflowEntranceSecurityRoleByName(final ExecutionErrorAccumulator eea, final String workflowName, 271 final String workflowEntranceName, final String partyTypeName, final String securityRoleName, 272 final EntityPermission entityPermission) { 273 var workflowEntrance = getWorkflowEntranceByName(eea, workflowName, workflowEntranceName); 274 var partyType = partyLogic.getPartyTypeByName(eea, partyTypeName); 275 WorkflowEntranceSecurityRole workflowEntranceSecurityRole = null; 276 277 if(eea == null || !eea.hasExecutionErrors()) { 278 var securityRoleGroup = workflowEntrance.getLastDetail().getWorkflow().getLastDetail().getSecurityRoleGroup(); 279 280 if(securityRoleGroup != null) { 281 var securityRole = securityRoleLogic.getSecurityRoleByName(eea, securityRoleGroup, securityRoleName); 282 283 if(eea == null || !eea.hasExecutionErrors()) { 284 var workflowEntrancePartyType = getWorkflowEntrancePartyType(eea, workflowEntrance, partyType); 285 286 if(eea == null || !eea.hasExecutionErrors()) { 287 workflowEntranceSecurityRole = workflowControl.getWorkflowEntranceSecurityRole(workflowEntrancePartyType, 288 securityRole, entityPermission); 289 290 if(workflowEntranceSecurityRole == null) { 291 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 292 var securityRoleDetail = securityRole.getLastDetail(); 293 294 handleExecutionError(UnknownWorkflowEntranceSecurityRoleException.class, eea, ExecutionErrors.UnknownWorkflowEntranceSecurityRole.name(), 295 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName(), 296 workflowEntranceDetail.getWorkflowEntranceName(), partyType.getPartyTypeName(), 297 securityRoleDetail.getSecurityRole().getLastDetail().getSecurityRoleName()); 298 } 299 } 300 } 301 } else { 302 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 303 304 handleExecutionError(WorkflowMissingSecurityRoleGroupException.class, eea, ExecutionErrors.WorkflowMissingSecurityRoleGroup.name(), 305 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName()); 306 } 307 } 308 309 return workflowEntranceSecurityRole; 310 } 311 312 public WorkflowEntranceSecurityRole getWorkflowEntranceSecurityRoleByName(final ExecutionErrorAccumulator eea, final String workflowName, 313 final String workflowEntranceName, final String partyTypeName, final String securityRoleName) { 314 return getWorkflowEntranceSecurityRoleByName(eea, workflowName, workflowEntranceName, partyTypeName, securityRoleName, 315 EntityPermission.READ_ONLY); 316 } 317 318 319 public WorkflowEntranceSecurityRole getWorkflowEntranceSecurityRoleByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 320 final String workflowEntranceName, final String partyTypeName, final String securityRoleName) { 321 return getWorkflowEntranceSecurityRoleByName(eea, workflowName, workflowEntranceName, partyTypeName, securityRoleName, 322 EntityPermission.READ_WRITE); 323 } 324 325 public WorkflowEntranceSelector getWorkflowEntranceSelectorByName(final ExecutionErrorAccumulator eea, final String workflowName, 326 final String workflowEntranceName, final String selectorName, final EntityPermission entityPermission) { 327 var workflowEntrance = getWorkflowEntranceByName(eea, workflowName, workflowEntranceName); 328 WorkflowEntranceSelector workflowEntranceSelector = null; 329 330 if(eea == null || !eea.hasExecutionErrors()) { 331 var selectorType = workflowEntrance.getLastDetail().getWorkflow().getLastDetail().getSelectorType(); 332 333 if(selectorType != null) { 334 var selector = selectorLogic.getSelectorByName(eea, selectorType, selectorName); 335 336 if(eea == null || !eea.hasExecutionErrors()) { 337 workflowEntranceSelector = workflowControl.getWorkflowEntranceSelector(workflowEntrance, 338 selector, entityPermission); 339 340 if(workflowEntranceSelector == null) { 341 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 342 var selectorDetail = selector.getLastDetail(); 343 344 handleExecutionError(UnknownWorkflowEntranceSelectorException.class, eea, ExecutionErrors.UnknownWorkflowEntranceSelector.name(), 345 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName(), 346 workflowEntranceDetail.getWorkflowEntranceName(), 347 selectorDetail.getSelector().getLastDetail().getSelectorName()); 348 } 349 } 350 } else { 351 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 352 353 handleExecutionError(WorkflowMissingSelectorTypeException.class, eea, ExecutionErrors.WorkflowMissingSelectorType.name(), 354 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName()); 355 } 356 } 357 358 return workflowEntranceSelector; 359 } 360 361 public WorkflowEntranceSelector getWorkflowEntranceSelectorByName(final ExecutionErrorAccumulator eea, final String workflowName, 362 final String workflowEntranceName, final String selectorName) { 363 return getWorkflowEntranceSelectorByName(eea, workflowName, workflowEntranceName, selectorName, 364 EntityPermission.READ_ONLY); 365 } 366 367 368 public WorkflowEntranceSelector getWorkflowEntranceSelectorByNameForUpdate(final ExecutionErrorAccumulator eea, final String workflowName, 369 final String workflowEntranceName, final String selectorName) { 370 return getWorkflowEntranceSelectorByName(eea, workflowName, workflowEntranceName, selectorName, 371 EntityPermission.READ_WRITE); 372 } 373 374 public WorkflowStep getEntranceWorkflowStep(final ExecutionErrorAccumulator eea, final String entranceWorkflowName, 375 final String entranceWorkflowStepName) { 376 return workflowStepLogic.getWorkflowStepByName( 377 UnknownEntranceWorkflowNameException.class, ExecutionErrors.UnknownEntranceWorkflowName, 378 UnknownEntranceWorkflowStepNameException.class, ExecutionErrors.UnknownEntranceWorkflowStepName, 379 eea, entranceWorkflowName, entranceWorkflowStepName); 380 } 381 382 public WorkflowEntranceStep getWorkflowEntranceStep(final ExecutionErrorAccumulator eea, 383 WorkflowEntrance workflowEntrance, WorkflowStep entranceWorkflowStep) { 384 var workflowEntranceStep = workflowControl.getWorkflowEntranceStep(workflowEntrance, entranceWorkflowStep); 385 386 if(workflowEntranceStep == null) { 387 var workflowEntranceDetail = workflowEntrance.getLastDetail(); 388 var entranceWorkflowStepDetail = entranceWorkflowStep.getLastDetail(); 389 390 handleExecutionError(UnknownWorkflowEntranceStepException.class, eea, ExecutionErrors.UnknownWorkflowEntranceStep.name(), 391 workflowEntranceDetail.getWorkflow().getLastDetail().getWorkflowName(), 392 workflowEntranceDetail.getWorkflowEntranceName(), 393 entranceWorkflowStepDetail.getWorkflow().getLastDetail().getWorkflowName(), 394 entranceWorkflowStepDetail.getWorkflowStepName()); 395 } 396 397 return workflowEntranceStep; 398 } 399 400 public WorkflowEntranceStep getWorkflowEntranceStepByName(final ExecutionErrorAccumulator eea, 401 final String workflowName, final String workflowEntranceName, final String entranceWorkflowName, 402 final String entranceWorkflowStepName) { 403 var workflowEntrance = getWorkflowEntranceByName(eea, workflowName, workflowEntranceName); 404 var entranceWorkflowStep = getEntranceWorkflowStep(eea, entranceWorkflowName, entranceWorkflowStepName); 405 WorkflowEntranceStep workflowEntranceStep = null; 406 407 if(eea == null || !eea.hasExecutionErrors()) { 408 workflowEntranceStep = getWorkflowEntranceStep(eea, workflowEntrance, entranceWorkflowStep); 409 } 410 411 return workflowEntranceStep; 412 } 413 414}