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