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.chain.server.logic; 018 019import com.echothree.control.user.chain.common.spec.ChainInstanceUniversalSpec; 020import com.echothree.model.control.chain.common.exception.UnknownChainInstanceNameException; 021import com.echothree.model.control.chain.server.control.ChainControl; 022import com.echothree.model.control.core.common.ComponentVendors; 023import com.echothree.model.control.core.common.EntityTypes; 024import com.echothree.model.control.core.common.exception.InvalidParameterCountException; 025import com.echothree.model.control.core.server.logic.EntityInstanceLogic; 026import com.echothree.model.control.sequence.common.SequenceTypes; 027import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic; 028import com.echothree.model.data.chain.server.entity.Chain; 029import com.echothree.model.data.chain.server.entity.ChainEntityRoleType; 030import com.echothree.model.data.chain.server.entity.ChainInstance; 031import com.echothree.model.data.chain.server.entity.ChainType; 032import com.echothree.model.data.core.server.entity.EntityInstance; 033import com.echothree.model.data.party.server.entity.Party; 034import com.echothree.util.common.message.ExecutionErrors; 035import com.echothree.util.common.persistence.BasePK; 036import com.echothree.util.server.control.BaseLogic; 037import com.echothree.util.server.message.ExecutionErrorAccumulator; 038import com.echothree.util.server.persistence.EntityPermission; 039import java.util.HashSet; 040import java.util.Set; 041import javax.enterprise.context.ApplicationScoped; 042import javax.enterprise.inject.spi.CDI; 043import javax.inject.Inject; 044 045@ApplicationScoped 046public class ChainInstanceLogic 047 extends BaseLogic { 048 049 public static ChainInstanceLogic getInstance() { 050 return CDI.current().select(ChainInstanceLogic.class).get(); 051 } 052 053 @Inject 054 protected ChainControl chainControl; 055 056 @Inject 057 protected ChainLogic chainLogic; 058 059 @Inject 060 protected ChainTypeLogic chainTypeLogic; 061 062 @Inject 063 EntityInstanceLogic entityInstanceLogic; 064 065 @Inject 066 SequenceGeneratorLogic sequenceGeneratorLogic; 067 068 protected ChainInstanceLogic() { 069 super(); 070 } 071 072 public ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final Chain chain, final BasePK createdBy) { 073 var defaultChainActionSet = chainControl.getDefaultChainActionSet(chain); 074 ChainInstance chainInstance = null; 075 076 // The lack of a defaultChainActionSet is not a reportable error - it just silently avoids creating a Chain Instance. 077 if(defaultChainActionSet != null) { 078 var sequence = chain.getLastDetail().getChainInstanceSequence(); 079 080 if(sequence == null) { 081 sequence = sequenceGeneratorLogic.getDefaultSequence(eea, SequenceTypes.CHAIN_INSTANCE.name()); 082 } 083 084 if(!hasExecutionErrors(eea)) { 085 chainInstance = chainControl.createChainInstance(sequenceGeneratorLogic.getNextSequenceValue(sequence), defaultChainActionSet, createdBy); 086 } 087 } 088 089 return chainInstance; 090 } 091 092 public ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final ChainType chainType, final Party party, final BasePK createdBy) { 093 var chain = chainLogic.getChain(eea, chainType, party); 094 ChainInstance chainInstance = null; 095 096 if(chain != null) { 097 chainInstance = createChainInstance(eea, chain, createdBy); 098 } 099 100 return chainInstance; 101 } 102 103 public ChainInstance createChainInstance(final ExecutionErrorAccumulator eea, final String chainKindName, final String chainTypeName, final Party party, 104 final BasePK createdBy) { 105 var chainType = chainTypeLogic.getChainTypeByName(eea, chainKindName, chainTypeName); 106 ChainInstance chainInstance = null; 107 108 if(!hasExecutionErrors(eea)) { 109 chainInstance = createChainInstance(eea, chainType, party, createdBy); 110 } 111 112 return chainInstance; 113 } 114 115 public ChainInstance getChainInstanceByName(final ExecutionErrorAccumulator eea, final String chainInstanceName, 116 final EntityPermission entityPermission) { 117 var chainInstance = chainControl.getChainInstanceByName(chainInstanceName, entityPermission); 118 119 if(chainInstance == null) { 120 handleExecutionError(UnknownChainInstanceNameException.class, eea, ExecutionErrors.UnknownChainInstanceName.name(), chainInstanceName); 121 } 122 123 return chainInstance; 124 } 125 126 public ChainInstance getChainInstanceByName(final ExecutionErrorAccumulator eea, final String chainInstanceName) { 127 return getChainInstanceByName(eea, chainInstanceName, EntityPermission.READ_ONLY); 128 } 129 130 public ChainInstance getChainInstanceByNameForUpdate(final ExecutionErrorAccumulator eea, final String chainInstanceName) { 131 return getChainInstanceByName(eea, chainInstanceName, EntityPermission.READ_WRITE); 132 } 133 134 public ChainInstance getChainInstanceByUniversalSpec(final ExecutionErrorAccumulator eea, 135 final ChainInstanceUniversalSpec universalSpec, final EntityPermission entityPermission) { 136 ChainInstance chainInstance = null; 137 var chainInstanceName = universalSpec.getChainInstanceName(); 138 var parameterCount = (chainInstanceName == null ? 0 : 1) + entityInstanceLogic.countPossibleEntitySpecs(universalSpec); 139 140 switch(parameterCount) { 141 case 1 -> { 142 if(chainInstanceName == null) { 143 var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec, 144 ComponentVendors.ECHO_THREE.name(), EntityTypes.ChainInstance.name()); 145 146 if(eea == null || !eea.hasExecutionErrors()) { 147 chainInstance = chainControl.getChainInstanceByEntityInstance(entityInstance, entityPermission); 148 } 149 } else { 150 chainInstance = getChainInstanceByName(eea, chainInstanceName, entityPermission); 151 } 152 } 153 default -> 154 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 155 } 156 157 return chainInstance; 158 } 159 160 public ChainInstance getChainInstanceByUniversalSpec(final ExecutionErrorAccumulator eea, 161 final ChainInstanceUniversalSpec universalSpec) { 162 return getChainInstanceByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY); 163 } 164 165 public ChainInstance getChainInstanceByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, 166 final ChainInstanceUniversalSpec universalSpec) { 167 return getChainInstanceByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE); 168 } 169 170 public void deleteChainInstanceByChainEntityRoleTypeAndEntityInstance(final ChainEntityRoleType chainEntityRoleType, final EntityInstance entityInstance, 171 final BasePK deletedBy) { 172 var chainInstanceEntityRoles = chainControl.getChainInstanceEntityRoles(chainEntityRoleType, entityInstance); 173 Set<ChainInstance> chainInstances = new HashSet<>(); 174 175 chainInstanceEntityRoles.forEach((chainInstanceEntityRole) -> { 176 chainInstances.add(chainInstanceEntityRole.getChainInstanceForUpdate()); 177 }); 178 179 chainControl.deleteChainInstances(chainInstances, deletedBy); 180 } 181 182}