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