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.selector.server.logic;
018
019import com.echothree.control.user.selector.common.spec.SelectorUniversalSpec;
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.selector.common.exception.DuplicateSelectorNameException;
025import com.echothree.model.control.selector.common.exception.UnknownDefaultSelectorException;
026import com.echothree.model.control.selector.common.exception.UnknownDefaultSelectorKindException;
027import com.echothree.model.control.selector.common.exception.UnknownDefaultSelectorTypeException;
028import com.echothree.model.control.selector.common.exception.UnknownSelectorNameException;
029import com.echothree.model.control.selector.server.control.SelectorControl;
030import com.echothree.model.data.party.server.entity.Language;
031import com.echothree.model.data.selector.server.entity.Selector;
032import com.echothree.model.data.selector.server.entity.SelectorKind;
033import com.echothree.model.data.selector.server.entity.SelectorType;
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 com.echothree.util.server.validation.ParameterUtils;
040import javax.enterprise.context.ApplicationScoped;
041import javax.inject.Inject;
042
043@ApplicationScoped
044public class SelectorLogic
045        extends BaseLogic {
046
047    @Inject
048    SelectorControl selectorControl;
049
050    @Inject
051    EntityInstanceLogic entityInstanceLogic;
052
053    @Inject
054    SelectorKindLogic selectorKindLogic;
055
056    @Inject
057    SelectorTypeLogic selectorTypeLogic;
058
059    protected SelectorLogic() {
060        super();
061    }
062
063    public Selector createSelector(final ExecutionErrorAccumulator eea, final String selectorKindName, final String selectorTypeName,
064            final String selectorName, final Boolean isDefault, final Integer sortOrder, final Language language, final String description,
065            final BasePK createdBy) {
066        var selectorType = selectorTypeLogic.getSelectorTypeByName(eea, selectorKindName, selectorTypeName);
067        Selector selector = null;
068
069        if(eea == null || !eea.hasExecutionErrors()) {
070            selector = createSelector(eea, selectorType, selectorName, isDefault, sortOrder, language, description, createdBy);
071        }
072
073        return selector;
074    }
075
076    public Selector createSelector(final ExecutionErrorAccumulator eea, final SelectorType selectorType, final String selectorName,
077            final Boolean isDefault, final Integer sortOrder, final Language language, final String description, final BasePK createdBy) {
078        var selector = selectorControl.getSelectorByName(selectorType, selectorName);
079
080        if(selector == null) {
081            selector = selectorControl.createSelector(selectorType, selectorName, isDefault, sortOrder, createdBy);
082
083            if(description != null) {
084                selectorControl.createSelectorDescription(selector, language, description, createdBy);
085            }
086        } else {
087            handleExecutionError(DuplicateSelectorNameException.class, eea, ExecutionErrors.DuplicateSelectorName.name(),
088                    selectorType.getLastDetail().getSelectorKind().getLastDetail().getSelectorKindName(),
089                    selectorType.getLastDetail().getSelectorTypeName(), selectorName);
090        }
091        return selector;
092    }
093
094    public Selector getSelectorByName(final ExecutionErrorAccumulator eea, final SelectorType selectorType, final String selectorName,
095            final EntityPermission entityPermission) {
096        var selector = selectorControl.getSelectorByName(selectorType, selectorName, entityPermission);
097
098        if(selector == null) {
099            var selectorTypeDetail = selectorType.getLastDetail();
100
101            handleExecutionError(UnknownSelectorNameException.class, eea, ExecutionErrors.UnknownSelectorName.name(),
102                    selectorTypeDetail.getSelectorKind().getLastDetail().getSelectorKindName(),
103                    selectorTypeDetail.getSelectorTypeName(), selectorName);
104        }
105
106        return selector;
107    }
108
109    public Selector getSelectorByName(final ExecutionErrorAccumulator eea, final SelectorType selectorType, final String selectorName) {
110        return getSelectorByName(eea, selectorType, selectorName, EntityPermission.READ_ONLY);
111    }
112
113    public Selector getSelectorByNameForUpdate(final ExecutionErrorAccumulator eea, final SelectorType selectorType, final String selectorName) {
114        return getSelectorByName(eea, selectorType, selectorName, EntityPermission.READ_WRITE);
115    }
116
117    public Selector getSelectorByName(final ExecutionErrorAccumulator eea, final String selectorKindName,
118            final String selectorTypeName, final String selectorName, final EntityPermission entityPermission) {
119        var selectorType = selectorTypeLogic.getSelectorTypeByName(eea, selectorKindName, selectorTypeName);
120        Selector selector = null;
121
122        if(eea == null || !eea.hasExecutionErrors()) {
123            selector = getSelectorByName(eea, selectorType, selectorName, entityPermission);
124        }
125
126        return selector;
127    }
128
129    public Selector getSelectorByName(final ExecutionErrorAccumulator eea, final String selectorKindName,
130            final String selectorType, final String selectorName) {
131        return getSelectorByName(eea, selectorKindName, selectorType, selectorName, EntityPermission.READ_ONLY);
132    }
133
134    public Selector getSelectorByNameForUpdate(final ExecutionErrorAccumulator eea, final String selectorKindName,
135            final String selectorType, final String selectorName) {
136        return getSelectorByName(eea, selectorKindName, selectorType, selectorName, EntityPermission.READ_WRITE);
137    }
138
139    public Selector getSelectorByUniversalSpec(final ExecutionErrorAccumulator eea, final SelectorUniversalSpec universalSpec,
140            final boolean allowDefault, final EntityPermission entityPermission) {
141        var selectorKindName = universalSpec.getSelectorKindName();
142        var selectorTypeName = universalSpec.getSelectorTypeName();
143        var selectorName = universalSpec.getSelectorName();
144        var nameParameterCount= ParameterUtils.getInstance().countNonNullParameters(selectorKindName, selectorTypeName, selectorName);
145        var possibleEntitySpecs= entityInstanceLogic.countPossibleEntitySpecs(universalSpec);
146        Selector selector = null;
147
148        if(nameParameterCount < 4 && possibleEntitySpecs == 0) {
149            SelectorKind selectorKind = null;
150            SelectorType selectorType = null;
151
152            if(selectorKindName == null) {
153                if(allowDefault) {
154                    selectorKind = selectorControl.getDefaultSelectorKind();
155
156                    if(selectorKind == null) {
157                        handleExecutionError(UnknownDefaultSelectorKindException.class, eea, ExecutionErrors.UnknownDefaultSelectorKind.name());
158                    }
159                } else {
160                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
161                }
162            } else {
163                selectorKind = selectorKindLogic.getSelectorKindByName(eea, selectorKindName);
164            }
165
166            if(selectorTypeName == null) {
167                if(allowDefault) {
168                    selectorType = selectorControl.getDefaultSelectorType(selectorKind);
169
170                    if(selectorType == null) {
171                        handleExecutionError(UnknownDefaultSelectorTypeException.class, eea, ExecutionErrors.UnknownDefaultSelectorType.name());
172                    }
173                } else {
174                    handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
175                }
176            } else {
177                selectorType = selectorTypeLogic.getSelectorTypeByName(eea, selectorKind, selectorTypeName);
178            }
179
180            if(eea == null || !eea.hasExecutionErrors()) {
181                if(selectorName == null) {
182                    if(allowDefault) {
183                        selector = selectorControl.getDefaultSelector(selectorType, entityPermission);
184
185                        if(selector == null) {
186                            handleExecutionError(UnknownDefaultSelectorException.class, eea, ExecutionErrors.UnknownDefaultSelector.name());
187                        }
188                    } else {
189                        handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
190                    }
191                } else {
192                    selector = getSelectorByName(eea, selectorType, selectorName, entityPermission);
193                }
194            }
195        } else if(nameParameterCount == 0 && possibleEntitySpecs == 1) {
196            var entityInstance = entityInstanceLogic.getEntityInstance(eea, universalSpec,
197                    ComponentVendors.ECHO_THREE.name(), EntityTypes.Selector.name());
198
199            if(eea == null || !eea.hasExecutionErrors()) {
200                selector = selectorControl.getSelectorByEntityInstance(entityInstance, entityPermission);
201            }
202        } else {
203            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
204        }
205
206        return selector;
207    }
208
209    public Selector getSelectorByUniversalSpec(final ExecutionErrorAccumulator eea, final SelectorUniversalSpec universalSpec,
210            boolean allowDefault) {
211        return getSelectorByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_ONLY);
212    }
213
214    public Selector getSelectorByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final SelectorUniversalSpec universalSpec,
215            boolean allowDefault) {
216        return getSelectorByUniversalSpec(eea, universalSpec, allowDefault, EntityPermission.READ_WRITE);
217    }
218
219}