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.ChainActionUniversalSpec;
020import com.echothree.model.control.chain.common.exception.UnknownChainActionNameException;
021import com.echothree.model.control.chain.common.exception.UnknownDefaultChainActionSetException;
022import com.echothree.model.control.chain.common.exception.UnknownDefaultChainException;
023import com.echothree.model.control.chain.common.exception.UnknownDefaultChainKindException;
024import com.echothree.model.control.chain.common.exception.UnknownDefaultChainTypeException;
025import com.echothree.model.control.chain.server.control.ChainControl;
026import com.echothree.model.control.core.common.ComponentVendors;
027import com.echothree.model.control.core.common.EntityTypes;
028import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
029import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
030import com.echothree.model.data.chain.server.entity.Chain;
031import com.echothree.model.data.chain.server.entity.ChainAction;
032import com.echothree.model.data.chain.server.entity.ChainActionSet;
033import com.echothree.model.data.chain.server.entity.ChainKind;
034import com.echothree.model.data.chain.server.entity.ChainType;
035import com.echothree.util.common.message.ExecutionErrors;
036import com.echothree.util.server.control.BaseLogic;
037import com.echothree.util.server.message.ExecutionErrorAccumulator;
038import com.echothree.util.server.persistence.EntityPermission;
039import com.echothree.util.server.validation.ParameterUtils;
040import javax.enterprise.context.ApplicationScoped;
041import javax.inject.Inject;
042
043@ApplicationScoped
044public class ChainActionLogic
045        extends BaseLogic {
046
047    @Inject
048    ChainControl chainControl;
049
050    @Inject
051    ChainActionSetLogic chainActionSetLogic;
052
053    @Inject
054    ChainKindLogic chainKindLogic;
055
056    @Inject
057    ChainLogic chainLogic;
058
059    @Inject
060    ChainTypeLogic chainTypeLogic;
061
062    @Inject
063    EntityInstanceLogic entityInstanceLogic;
064
065    @Inject
066    ParameterUtils parameterUtils;
067
068    protected ChainActionLogic() {
069        super();
070    }
071
072    public ChainAction getChainActionByName(final ExecutionErrorAccumulator eea, final ChainActionSet chainActionSet, final String chainActionName,
073            final EntityPermission entityPermission) {
074        var chainAction = entityPermission == EntityPermission.READ_WRITE
075                ? chainControl.getChainActionByNameForUpdate(chainActionSet, chainActionName)
076                : chainControl.getChainActionByName(chainActionSet, chainActionName);
077
078        if(chainAction == null) {
079            handleExecutionError(UnknownChainActionNameException.class, eea, ExecutionErrors.UnknownChainActionName.name(),
080                    chainActionSet.getLastDetail().getChain().getLastDetail().getChainType().getLastDetail().getChainKind().getLastDetail().getChainKindName(),
081                    chainActionSet.getLastDetail().getChain().getLastDetail().getChainType().getLastDetail().getChainTypeName(),
082                    chainActionSet.getLastDetail().getChain().getLastDetail().getChainName(),
083                    chainActionSet.getLastDetail().getChainActionSetName(),
084                    chainActionName);
085        }
086
087        return chainAction;
088    }
089
090    public ChainAction getChainActionByName(final ExecutionErrorAccumulator eea, final ChainActionSet chainActionSet, final String chainActionName) {
091        return getChainActionByName(eea, chainActionSet, chainActionName, EntityPermission.READ_ONLY);
092    }
093
094    public ChainAction getChainActionByNameForUpdate(final ExecutionErrorAccumulator eea, final ChainActionSet chainActionSet, final String chainActionName) {
095        return getChainActionByName(eea, chainActionSet, chainActionName, EntityPermission.READ_WRITE);
096    }
097
098    public ChainAction getChainActionByName(final ExecutionErrorAccumulator eea, final String chainKindName,
099            final String chainTypeName, final String chainName, final String chainActionSetName, final String chainActionName,
100            final EntityPermission entityPermission) {
101        var chainActionSet = chainActionSetLogic.getChainActionSetByName(eea, chainKindName, chainTypeName, chainName, chainActionSetName);
102        ChainAction chainAction = null;
103
104        if(!hasExecutionErrors(eea)) {
105            chainAction = getChainActionByName(eea, chainActionSet, chainActionName, entityPermission);
106        }
107
108        return chainAction;
109    }
110
111    public ChainAction getChainActionByName(final ExecutionErrorAccumulator eea, final String chainKindName,
112            final String chainTypeName, final String chainName, final String chainActionSetName, final String chainActionName) {
113        return getChainActionByName(eea, chainKindName, chainTypeName, chainName, chainActionSetName, chainActionName, EntityPermission.READ_ONLY);
114    }
115
116    public ChainAction getChainActionByNameForUpdate(final ExecutionErrorAccumulator eea, final String chainKindName,
117            final String chainTypeName, final String chainName, final String chainActionSetName, final String chainActionName) {
118        return getChainActionByName(eea, chainKindName, chainTypeName, chainName, chainActionSetName, chainActionName, EntityPermission.READ_WRITE);
119    }
120
121    public ChainAction getChainActionByUniversalSpec(final ExecutionErrorAccumulator eea,
122            final ChainActionUniversalSpec universalSpec, final boolean allowDefault, final EntityPermission entityPermission) {
123        var chainKindName = universalSpec.getChainKindName();
124        var chainTypeName = universalSpec.getChainTypeName();
125        var chainName = universalSpec.getChainName();
126        var chainActionSetName = universalSpec.getChainActionSetName();
127        var chainActionName = universalSpec.getChainActionName();
128        var nameParameterCount = parameterUtils.countNonNullParameters(chainKindName, chainTypeName, chainName, chainActionSetName, chainActionName);
129        var possibleEntitySpecs = entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
130        ChainAction chainAction = null;
131
132        if(nameParameterCount != 0 && possibleEntitySpecs == 0) {
133            ChainKind chainKind = null;
134            ChainType chainType = null;
135            Chain chain = null;
136            ChainActionSet chainActionSet = null;
137
138            if(chainKindName == null) {
139                if(allowDefault) {
140                    chainKind = chainControl.getDefaultChainKind();
141
142                    if(chainKind == null) {
143                        handleExecutionError(UnknownDefaultChainKindException.class, eea, ExecutionErrors.UnknownDefaultChainKind.name());
144                    }
145                } else {
146                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
147                }
148            } else {
149                chainKind = chainKindLogic.getChainKindByName(eea, chainKindName);
150            }
151
152            if(!eea.hasExecutionErrors()) {
153                if(chainTypeName == null) {
154                    if(allowDefault) {
155                        chainType = chainControl.getDefaultChainType(chainKind);
156
157                        if(chainType == null) {
158                            handleExecutionError(UnknownDefaultChainTypeException.class, eea, ExecutionErrors.UnknownDefaultChainType.name(),
159                                    chainKind.getLastDetail().getChainKindName());
160                        }
161                    } else {
162                        handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
163                    }
164                } else {
165                    chainType = chainTypeLogic.getChainTypeByName(eea, chainKind, chainTypeName);
166                }
167            }
168
169            if(!eea.hasExecutionErrors()) {
170                if(chainName == null) {
171                    if(allowDefault) {
172                        chain = chainControl.getDefaultChain(chainType, entityPermission);
173
174                        if(chain == null) {
175                            handleExecutionError(UnknownDefaultChainException.class, eea, ExecutionErrors.UnknownDefaultChain.name(),
176                                    chainKind.getLastDetail().getChainKindName(),
177                                    chainType.getLastDetail().getChainTypeName());
178                        }
179                    } else {
180                        handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
181                    }
182                } else {
183                    chain = chainLogic.getChainByName(eea, chainType, chainName, entityPermission);
184                }
185            }
186
187            if(!eea.hasExecutionErrors()) {
188                if(chainActionSetName == null) {
189                    if(allowDefault) {
190                        chainActionSet = chainControl.getDefaultChainActionSet(chain, entityPermission);
191
192                        if(chainActionSet == null) {
193                            handleExecutionError(UnknownDefaultChainActionSetException.class, eea, ExecutionErrors.UnknownDefaultChainActionSet.name(),
194                                    chain.getLastDetail().getChainType().getLastDetail().getChainKind().getLastDetail().getChainKindName(),
195                                    chain.getLastDetail().getChainType().getLastDetail().getChainTypeName(),
196                                    chain.getLastDetail().getChainName());
197                        }
198                    } else {
199                        handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
200                    }
201                } else {
202                    chainActionSet = chainActionSetLogic.getChainActionSetByName(eea, chain, chainActionSetName, entityPermission);
203                }
204            }
205
206            if(!eea.hasExecutionErrors()) {
207                if(chainActionName != null) {
208                    chainAction = getChainActionByName(eea, chainActionSet, chainActionName, entityPermission);
209                } else {
210                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
211                }
212            }
213        } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) {
214            var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
215                    ComponentVendors.ECHO_THREE.name(), EntityTypes.ChainAction.name());
216
217            if(!eea.hasExecutionErrors()) {
218                chainAction = chainControl.getChainActionByEntityInstance(entityInstance, entityPermission);
219            }
220        } else {
221            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
222        }
223
224        return chainAction;
225    }
226
227    public ChainAction getChainActionByUniversalSpec(final ExecutionErrorAccumulator eea,
228            final ChainActionUniversalSpec universalSpec, final boolean allowDefault) {
229        return getChainActionByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY);
230    }
231
232    public ChainAction getChainActionByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea,
233            final ChainActionUniversalSpec universalSpec, final boolean allowDefault) {
234        return getChainActionByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE);
235    }
236
237}