001// --------------------------------------------------------------------------------
002// Copyright 2002-2025 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.core.server.logic;
018
019import com.echothree.control.user.core.common.edit.EntityListItemAttributeEdit;
020import com.echothree.control.user.core.common.spec.EntityAttributeSpec;
021import com.echothree.control.user.core.common.spec.EntityAttributeUniversalSpec;
022import com.echothree.control.user.core.common.spec.EntityAttributeUuid;
023import com.echothree.control.user.core.common.spec.EntityInstanceAttributeSpec;
024import com.echothree.control.user.core.common.spec.EntityListItemUniversalSpec;
025import com.echothree.control.user.core.common.spec.EntityListItemUuid;
026import com.echothree.model.control.core.common.ComponentVendors;
027import com.echothree.model.control.core.common.EntityAttributeTypes;
028import com.echothree.model.control.core.common.EntityTypes;
029import com.echothree.model.control.core.common.exception.DuplicateEntityAttributeNameException;
030import com.echothree.model.control.core.common.exception.DuplicateEntityBooleanAttributeException;
031import com.echothree.model.control.core.common.exception.DuplicateEntityBooleanDefaultException;
032import com.echothree.model.control.core.common.exception.DuplicateEntityClobAttributeException;
033import com.echothree.model.control.core.common.exception.DuplicateEntityDateAttributeException;
034import com.echothree.model.control.core.common.exception.DuplicateEntityDateDefaultException;
035import com.echothree.model.control.core.common.exception.DuplicateEntityGeoPointAttributeException;
036import com.echothree.model.control.core.common.exception.DuplicateEntityGeoPointDefaultException;
037import com.echothree.model.control.core.common.exception.DuplicateEntityIntegerAttributeException;
038import com.echothree.model.control.core.common.exception.DuplicateEntityIntegerDefaultException;
039import com.echothree.model.control.core.common.exception.DuplicateEntityListItemAttributeException;
040import com.echothree.model.control.core.common.exception.DuplicateEntityListItemDefaultException;
041import com.echothree.model.control.core.common.exception.DuplicateEntityListItemNameException;
042import com.echothree.model.control.core.common.exception.DuplicateEntityLongAttributeException;
043import com.echothree.model.control.core.common.exception.DuplicateEntityLongDefaultException;
044import com.echothree.model.control.core.common.exception.DuplicateEntityMultipleListItemAttributeException;
045import com.echothree.model.control.core.common.exception.DuplicateEntityMultipleListItemDefaultException;
046import com.echothree.model.control.core.common.exception.DuplicateEntityNameAttributeException;
047import com.echothree.model.control.core.common.exception.DuplicateEntityStringAttributeException;
048import com.echothree.model.control.core.common.exception.DuplicateEntityStringDefaultException;
049import com.echothree.model.control.core.common.exception.DuplicateEntityTimeAttributeException;
050import com.echothree.model.control.core.common.exception.DuplicateEntityTimeDefaultException;
051import com.echothree.model.control.core.common.exception.DuplicateWorkflowUsageInEntityAttributeException;
052import com.echothree.model.control.core.common.exception.EntityTypeIsNotExtensibleException;
053import com.echothree.model.control.core.common.exception.InvalidEntityAttributeTypeException;
054import com.echothree.model.control.core.common.exception.InvalidParameterCountException;
055import com.echothree.model.control.core.common.exception.InvalidStringAttributeException;
056import com.echothree.model.control.core.common.exception.LowerRangeExceededException;
057import com.echothree.model.control.core.common.exception.MismatchedEntityAttributeTypeException;
058import com.echothree.model.control.core.common.exception.MismatchedEntityListItemException;
059import com.echothree.model.control.core.common.exception.MismatchedEntityTypeException;
060import com.echothree.model.control.core.common.exception.UnknownEntityAttributeGroupNameException;
061import com.echothree.model.control.core.common.exception.UnknownEntityAttributeNameException;
062import com.echothree.model.control.core.common.exception.UnknownEntityAttributeTypeNameException;
063import com.echothree.model.control.core.common.exception.UnknownEntityBooleanDefaultException;
064import com.echothree.model.control.core.common.exception.UnknownEntityDateDefaultException;
065import com.echothree.model.control.core.common.exception.UnknownEntityGeoPointDefaultException;
066import com.echothree.model.control.core.common.exception.UnknownEntityIntegerDefaultException;
067import com.echothree.model.control.core.common.exception.UnknownEntityListItemDefaultException;
068import com.echothree.model.control.core.common.exception.UnknownEntityListItemNameException;
069import com.echothree.model.control.core.common.exception.UnknownEntityLongDefaultException;
070import com.echothree.model.control.core.common.exception.UnknownEntityMultipleListItemDefaultException;
071import com.echothree.model.control.core.common.exception.UnknownEntityStringDefaultException;
072import com.echothree.model.control.core.common.exception.UnknownEntityTimeDefaultException;
073import com.echothree.model.control.core.common.exception.UpperRangeExceededException;
074import com.echothree.model.control.core.server.database.EntityInstancePKResult;
075import com.echothree.model.control.core.server.database.EntityInstancePKsByBlobEntityAttributeQuery;
076import com.echothree.model.control.core.server.database.EntityInstancePKsByBooleanEntityAttributeQuery;
077import com.echothree.model.control.core.server.database.EntityInstancePKsByClobEntityAttributeQuery;
078import com.echothree.model.control.core.server.database.EntityInstancePKsByCollectionEntityAttributeQuery;
079import com.echothree.model.control.core.server.database.EntityInstancePKsByDateEntityAttributeQuery;
080import com.echothree.model.control.core.server.database.EntityInstancePKsByEntityEntityAttributeQuery;
081import com.echothree.model.control.core.server.database.EntityInstancePKsByGeoPointEntityAttributeQuery;
082import com.echothree.model.control.core.server.database.EntityInstancePKsByIntegerEntityAttributeQuery;
083import com.echothree.model.control.core.server.database.EntityInstancePKsByListItemEntityAttributeQuery;
084import com.echothree.model.control.core.server.database.EntityInstancePKsByLongEntityAttributeQuery;
085import com.echothree.model.control.core.server.database.EntityInstancePKsByMultipleListItemEntityAttributeQuery;
086import com.echothree.model.control.core.server.database.EntityInstancePKsByNameEntityAttributeQuery;
087import com.echothree.model.control.core.server.database.EntityInstancePKsByStringEntityAttributeQuery;
088import com.echothree.model.control.core.server.database.EntityInstancePKsByTimeEntityAttributeQuery;
089import com.echothree.model.control.core.server.database.EntityInstancesMissingBooleanEntityAttributeQuery;
090import com.echothree.model.control.core.server.database.EntityInstancesMissingDateEntityAttributeQuery;
091import com.echothree.model.control.core.server.database.EntityInstancesMissingGeoPointEntityAttributeQuery;
092import com.echothree.model.control.core.server.database.EntityInstancesMissingIntegerEntityAttributeQuery;
093import com.echothree.model.control.core.server.database.EntityInstancesMissingListItemEntityAttributeQuery;
094import com.echothree.model.control.core.server.database.EntityInstancesMissingLongEntityAttributeQuery;
095import com.echothree.model.control.core.server.database.EntityInstancesMissingMultipleListItemEntityAttributeQuery;
096import com.echothree.model.control.core.server.database.EntityInstancesMissingStringEntityAttributeQuery;
097import com.echothree.model.control.core.server.database.EntityInstancesMissingTimeEntityAttributeQuery;
098import com.echothree.model.control.index.server.control.IndexControl;
099import com.echothree.model.control.queue.common.QueueTypes;
100import com.echothree.model.control.queue.server.control.QueueControl;
101import com.echothree.model.control.queue.server.logic.QueueTypeLogic;
102import com.echothree.model.control.sequence.common.SequenceTypes;
103import com.echothree.model.control.sequence.common.exception.MissingDefaultSequenceException;
104import com.echothree.model.control.sequence.server.control.SequenceControl;
105import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
106import com.echothree.model.control.workflow.common.exception.UnknownWorkflowEntityTypeException;
107import com.echothree.model.control.workflow.server.control.WorkflowControl;
108import com.echothree.model.data.core.server.entity.ComponentVendor;
109import com.echothree.model.data.core.server.entity.EntityAttribute;
110import com.echothree.model.data.core.server.entity.EntityAttributeGroup;
111import com.echothree.model.data.core.server.entity.EntityAttributeType;
112import com.echothree.model.data.core.server.entity.EntityBooleanAttribute;
113import com.echothree.model.data.core.server.entity.EntityBooleanDefault;
114import com.echothree.model.data.core.server.entity.EntityClobAttribute;
115import com.echothree.model.data.core.server.entity.EntityDateAttribute;
116import com.echothree.model.data.core.server.entity.EntityDateDefault;
117import com.echothree.model.data.core.server.entity.EntityGeoPointAttribute;
118import com.echothree.model.data.core.server.entity.EntityGeoPointDefault;
119import com.echothree.model.data.core.server.entity.EntityInstance;
120import com.echothree.model.data.core.server.entity.EntityIntegerAttribute;
121import com.echothree.model.data.core.server.entity.EntityIntegerDefault;
122import com.echothree.model.data.core.server.entity.EntityListItem;
123import com.echothree.model.data.core.server.entity.EntityListItemAttribute;
124import com.echothree.model.data.core.server.entity.EntityListItemDefault;
125import com.echothree.model.data.core.server.entity.EntityLongAttribute;
126import com.echothree.model.data.core.server.entity.EntityLongDefault;
127import com.echothree.model.data.core.server.entity.EntityMultipleListItemAttribute;
128import com.echothree.model.data.core.server.entity.EntityMultipleListItemDefault;
129import com.echothree.model.data.core.server.entity.EntityNameAttribute;
130import com.echothree.model.data.core.server.entity.EntityStringAttribute;
131import com.echothree.model.data.core.server.entity.EntityStringDefault;
132import com.echothree.model.data.core.server.entity.EntityTimeAttribute;
133import com.echothree.model.data.core.server.entity.EntityTimeDefault;
134import com.echothree.model.data.core.server.entity.EntityType;
135import com.echothree.model.data.core.server.entity.MimeType;
136import com.echothree.model.data.core.server.value.EntityAttributeDetailValue;
137import com.echothree.model.data.core.server.value.EntityListItemDetailValue;
138import com.echothree.model.data.party.common.pk.PartyPK;
139import com.echothree.model.data.party.server.entity.Language;
140import com.echothree.model.data.queue.server.value.QueuedEntityValue;
141import com.echothree.model.data.sequence.server.entity.Sequence;
142import com.echothree.model.data.uom.server.entity.UnitOfMeasureType;
143import com.echothree.model.data.workflow.server.entity.Workflow;
144import com.echothree.util.common.message.ExecutionErrors;
145import com.echothree.util.common.persistence.BasePK;
146import com.echothree.util.server.control.BaseLogic;
147import com.echothree.util.server.message.ExecutionErrorAccumulator;
148import com.echothree.util.server.persistence.EntityPermission;
149import com.echothree.util.server.persistence.Session;
150import java.util.ArrayList;
151import java.util.List;
152import java.util.regex.Pattern;
153import javax.enterprise.context.ApplicationScoped;
154import javax.enterprise.inject.spi.CDI;
155
156@ApplicationScoped
157public class EntityAttributeLogic
158        extends BaseLogic {
159
160    protected EntityAttributeLogic() {
161        super();
162    }
163
164    public static EntityAttributeLogic getInstance() {
165        return CDI.current().select(EntityAttributeLogic.class).get();
166    }
167    
168    public EntityAttributeType getEntityAttributeTypeByName(final ExecutionErrorAccumulator eea, final String entityAttributeTypeName) {
169        var entityAttributeType = coreControl.getEntityAttributeTypeByName(entityAttributeTypeName);
170
171        if(entityAttributeType == null) {
172            handleExecutionError(UnknownEntityAttributeTypeNameException.class, eea, ExecutionErrors.UnknownEntityAttributeTypeName.name(), entityAttributeTypeName);
173        }
174
175        return entityAttributeType;
176    }
177
178    public EntityAttributeType getEntityAttributeTypeByUuid(final ExecutionErrorAccumulator eea, final String uuid, final EntityPermission entityPermission) {
179        EntityAttributeType entityAttributeType = null;
180        
181        var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, (String)null, uuid,
182                ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityAttributeType.name());
183
184        if(eea == null || !eea.hasExecutionErrors()) {
185            entityAttributeType = coreControl.getEntityAttributeTypeByEntityInstance(entityInstance, entityPermission);
186        }
187
188        return entityAttributeType;
189    }
190    
191    public EntityAttributeType getEntityAttributeTypeByUuid(final ExecutionErrorAccumulator eea, final String uuid) {
192        return getEntityAttributeTypeByUuid(eea, uuid, EntityPermission.READ_ONLY);
193    }
194    
195    public EntityAttributeType getEntityAttributeTypeByUuidForUpdate(final ExecutionErrorAccumulator eea, final String uuid) {
196        return getEntityAttributeTypeByUuid(eea, uuid, EntityPermission.READ_WRITE);
197    }
198    
199    public EntityAttributeGroup getEntityAttributeGroupByName(final ExecutionErrorAccumulator eea, final String entityAttributeGroupName) {
200        var entityAttributeGroup = coreControl.getEntityAttributeGroupByName(entityAttributeGroupName);
201
202        if(entityAttributeGroup == null) {
203            handleExecutionError(UnknownEntityAttributeGroupNameException.class, eea, ExecutionErrors.UnknownEntityAttributeGroupName.name(),
204                    entityAttributeGroupName);
205        }
206
207        return entityAttributeGroup;
208    }
209
210    public EntityAttributeGroup getEntityAttributeGroupByUuid(final ExecutionErrorAccumulator eea, final String uuid, final EntityPermission entityPermission) {
211        EntityAttributeGroup entityAttributeGroup = null;
212        
213        var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, (String)null, uuid,
214                ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityAttributeGroup.name());
215
216        if(eea == null || !eea.hasExecutionErrors()) {
217            entityAttributeGroup = coreControl.getEntityAttributeGroupByEntityInstance(entityInstance, entityPermission);
218        }
219
220        return entityAttributeGroup;
221    }
222    
223    public EntityAttributeGroup getEntityAttributeGroupByUuid(final ExecutionErrorAccumulator eea, final String uuid) {
224        return getEntityAttributeGroupByUuid(eea, uuid, EntityPermission.READ_ONLY);
225    }
226    
227    public EntityAttributeGroup getEntityAttributeGroupByUuidForUpdate(final ExecutionErrorAccumulator eea, final String uuid) {
228        return getEntityAttributeGroupByUuid(eea, uuid, EntityPermission.READ_WRITE);
229    }
230    
231    public EntityAttribute createEntityAttribute(final ExecutionErrorAccumulator eea, final EntityType entityType,
232            String entityAttributeName, final EntityAttributeType entityAttributeType, final Boolean trackRevisions,
233            final Boolean checkContentWebAddress, final String validationPattern, final Integer upperRangeIntegerValue,
234            final Integer upperLimitIntegerValue, final Integer lowerLimitIntegerValue, final Integer lowerRangeIntegerValue,
235            final Long upperRangeLongValue, final Long upperLimitLongValue, final Long lowerLimitLongValue,
236            final Long lowerRangeLongValue, final Sequence entityListItemSequence, final UnitOfMeasureType unitOfMeasureType,
237            final Workflow workflow, final Integer sortOrder, final BasePK createdBy, final Language language,
238            final String description) {
239        EntityAttribute entityAttribute = null;
240        var entityTypeDetail = entityType.getLastDetail();
241
242        if(entityTypeDetail.getIsExtensible()) {
243            if(entityAttributeName == null) {
244                var sequenceControl = Session.getModelController(SequenceControl.class);
245                var sequence = sequenceControl.getDefaultSequenceUsingNames(SequenceTypes.ENTITY_ATTRIBUTE.name());
246
247                entityAttributeName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(sequence);
248            }
249
250            entityAttribute = coreControl.getEntityAttributeByName(entityType, entityAttributeName);
251
252            if(entityAttribute == null) {
253                var entityAttributeTypeEnum = EntityAttributeTypes.valueOf(entityAttributeType.getEntityAttributeTypeName());
254
255                switch(entityAttributeTypeEnum) {
256                    case WORKFLOW -> {
257                        if(coreControl.countEntityAttributesByEntityTypeAndWorkflow(entityType, workflow) != 0) {
258                            handleExecutionError(DuplicateWorkflowUsageInEntityAttributeException.class, eea, ExecutionErrors.DuplicateWorkflowUsageInEntityAttribute.name(),
259                                    entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(), entityTypeDetail.getEntityTypeName(),
260                                    workflow.getLastDetail().getWorkflowName());
261                        } else {
262                            var workflowControl = Session.getModelController(WorkflowControl.class);
263
264                            if(!workflowControl.workflowEntityTypeExists(workflow, entityType)) {
265                                handleExecutionError(UnknownWorkflowEntityTypeException.class, eea, ExecutionErrors.UnknownWorkflowEntityType.name(),
266                                        workflow.getLastDetail().getWorkflowName(), entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
267                                        entityTypeDetail.getEntityTypeName());
268                            }
269
270                        }
271                    }
272                    default -> {
273                        // Nothing required for other EntityAttributeTypes
274                    }
275                }
276
277                if(!hasExecutionErrors(eea)) {
278                    entityAttribute = coreControl.createEntityAttribute(entityType, entityAttributeName, entityAttributeType,
279                            trackRevisions, sortOrder, createdBy);
280
281                    if(description != null) {
282                        coreControl.createEntityAttributeDescription(entityAttribute, language, description, createdBy);
283                    }
284
285                    switch(entityAttributeTypeEnum) {
286                        case BLOB ->
287                                coreControl.createEntityAttributeBlob(entityAttribute, checkContentWebAddress, createdBy);
288                        case STRING -> {
289                            if(validationPattern != null) {
290                                coreControl.createEntityAttributeString(entityAttribute, validationPattern, createdBy);
291                            }
292                        }
293                        case INTEGER -> {
294                            if(upperRangeIntegerValue != null || upperLimitIntegerValue != null || lowerLimitIntegerValue != null || lowerRangeIntegerValue != null) {
295                                coreControl.createEntityAttributeInteger(entityAttribute, upperRangeIntegerValue, upperLimitIntegerValue,
296                                        lowerLimitIntegerValue, lowerRangeIntegerValue, createdBy);
297                            }
298                            if(unitOfMeasureType != null) {
299                                coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, createdBy);
300                            }
301                        }
302                        case LONG -> {
303                            if(upperRangeLongValue != null || upperLimitLongValue != null || lowerLimitLongValue != null || lowerRangeLongValue != null) {
304                                coreControl.createEntityAttributeLong(entityAttribute, upperRangeLongValue, upperLimitLongValue,
305                                        lowerLimitLongValue, lowerRangeLongValue, createdBy);
306                            }
307                            if(unitOfMeasureType != null) {
308                                coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, createdBy);
309                            }
310                        }
311                        case LISTITEM, MULTIPLELISTITEM -> {
312                            if(entityListItemSequence != null) {
313                                coreControl.createEntityAttributeListItem(entityAttribute, entityListItemSequence, createdBy);
314                            }
315                        }
316                        case WORKFLOW -> {
317                            if(workflow != null) {
318                                coreControl.createEntityAttributeWorkflow(entityAttribute, workflow, createdBy);
319                            }
320                        }
321                        default -> {
322                            // Nothing required for other EntityAttributeTypes
323                        }
324                    }
325                }
326            } else {
327                handleExecutionError(DuplicateEntityAttributeNameException.class, eea, ExecutionErrors.DuplicateEntityAttributeName.name(),
328                        entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(), entityTypeDetail.getEntityTypeName(), entityAttributeName);
329            }
330        } else {
331            handleExecutionError(EntityTypeIsNotExtensibleException.class, eea, ExecutionErrors.EntityTypeIsNotExtensible.name(),
332                    entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(), entityTypeDetail.getEntityTypeName());
333        }
334        
335        return entityAttribute;
336    }
337    
338    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final EntityType entityType,
339            final String entityAttributeName, EntityPermission entityPermission) {
340        var entityAttribute = coreControl.getEntityAttributeByName(entityType, entityAttributeName, entityPermission);
341
342        if(entityAttribute == null) {
343            var entityTypeDetail = entityType.getLastDetail();
344            
345            handleExecutionError(UnknownEntityAttributeNameException.class, eea, ExecutionErrors.UnknownEntityAttributeName.name(),
346                    entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(), entityTypeDetail.getEntityTypeName(), entityAttributeName);
347        }
348
349        return entityAttribute;
350    }
351
352    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final EntityType entityType,
353            final String entityAttributeName) {
354        return getEntityAttributeByName(eea, entityType, entityAttributeName, EntityPermission.READ_ONLY);
355    }
356    
357    public EntityAttribute getEntityAttributeByNameForUpdate(final ExecutionErrorAccumulator eea, final EntityType entityType,
358            final String entityAttributeName) {
359        return getEntityAttributeByName(eea, entityType, entityAttributeName, EntityPermission.READ_WRITE);
360    }
361    
362    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final ComponentVendor componentVendor,
363            final String entityTypeName, final String entityAttributeName, EntityPermission entityPermission) {
364        var entityType = EntityTypeLogic.getInstance().getEntityTypeByName(eea, componentVendor, entityTypeName);
365        EntityAttribute entityAttribute = null;
366        
367        if(eea == null || !eea.hasExecutionErrors()) {
368            entityAttribute = getEntityAttributeByName(eea, entityType, entityAttributeName, entityPermission);
369        }
370
371        return entityAttribute;
372    }
373
374    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final ComponentVendor componentVendor,
375            final String entityTypeName, final String entityAttributeName) {
376        return getEntityAttributeByName(eea, componentVendor, entityTypeName, entityAttributeName, EntityPermission.READ_ONLY);
377    }
378    
379    public EntityAttribute getEntityAttributeByNameForUpdate(final ExecutionErrorAccumulator eea, final ComponentVendor componentVendor,
380            final String entityTypeName, final String entityAttributeName) {
381        return getEntityAttributeByName(eea, componentVendor, entityTypeName, entityAttributeName, EntityPermission.READ_WRITE);
382    }
383    
384    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final String componentVendorName,
385            final String entityTypeName, final String entityAttributeName, EntityPermission entityPermission) {
386        var entityType = EntityTypeLogic.getInstance().getEntityTypeByName(eea, componentVendorName, entityTypeName);
387        EntityAttribute entityAttribute = null;
388        
389        if(eea == null || !eea.hasExecutionErrors()) {
390            entityAttribute = getEntityAttributeByName(eea, entityType, entityAttributeName, entityPermission);
391        }
392
393        return entityAttribute;
394    }
395    
396    public EntityAttribute getEntityAttributeByName(final ExecutionErrorAccumulator eea, final String componentVendorName,
397            final String entityTypeName, final String entityAttributeName) {
398        return getEntityAttributeByName(eea, componentVendorName, entityTypeName, entityAttributeName, EntityPermission.READ_ONLY);
399    }
400    
401    public EntityAttribute getEntityAttributeByNameForUpdate(final ExecutionErrorAccumulator eea, final String componentVendorName,
402            final String entityTypeName, final String entityAttributeName) {
403        return getEntityAttributeByName(eea, componentVendorName, entityTypeName, entityAttributeName, EntityPermission.READ_WRITE);
404    }
405    
406    public EntityAttribute getEntityAttributeByUuid(final ExecutionErrorAccumulator eea, final String uuid,
407            final EntityPermission entityPermission) {
408        EntityAttribute entityAttribute = null;
409        
410        var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, (String)null, uuid,
411                ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityAttribute.name());
412
413        if(eea == null || !eea.hasExecutionErrors()) {
414            entityAttribute = coreControl.getEntityAttributeByEntityInstance(entityInstance, entityPermission);
415        }
416
417        return entityAttribute;
418    }
419    
420    public EntityAttribute getEntityAttributeByUuid(final ExecutionErrorAccumulator eea, final String uuid) {
421        return getEntityAttributeByUuid(eea, uuid, EntityPermission.READ_ONLY);
422    }
423    
424    public EntityAttribute getEntityAttributeByUuidForUpdate(final ExecutionErrorAccumulator eea, final String uuid) {
425        return getEntityAttributeByUuid(eea, uuid, EntityPermission.READ_WRITE);
426    }
427
428    // For when we need to determine the EntityType from what the user passes in:
429    public EntityAttribute getEntityAttributeByUniversalSpec(final ExecutionErrorAccumulator eea, final EntityAttributeUniversalSpec universalSpec,
430            final EntityPermission entityPermission) {
431        EntityAttribute entityAttribute = null;
432        var componentVendorName = universalSpec.getComponentVendorName();
433        var entityTypeName = universalSpec.getEntityTypeName();
434        var entityAttributeName = universalSpec.getEntityAttributeName();
435        var universalSpecCount = EntityInstanceLogic.getInstance().countPossibleEntitySpecs(universalSpec);
436        var parameterCount = (componentVendorName == null && entityTypeName == null && entityAttributeName == null ? 0 : 1)
437                + universalSpecCount;
438
439        switch(parameterCount) {
440            case 1 -> {
441                if(universalSpecCount == 1) {
442                    var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, universalSpec,
443                            ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityAttribute.name());
444
445                    if(!eea.hasExecutionErrors()) {
446                        entityAttribute = coreControl.getEntityAttributeByEntityInstance(entityInstance, entityPermission);
447                    }
448                } else {
449                    entityAttribute = getEntityAttributeByName(eea, componentVendorName, entityTypeName, entityAttributeName, entityPermission);
450                }
451            }
452            default -> {
453                handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
454            }
455        }
456
457        return entityAttribute;
458    }
459
460    public EntityAttribute getEntityAttributeByUniversalSpec(final ExecutionErrorAccumulator eea, final EntityAttributeUniversalSpec universalSpec) {
461        return getEntityAttributeByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
462    }
463
464    public EntityAttribute getEntityAttributeByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final EntityAttributeUniversalSpec universalSpec) {
465        return getEntityAttributeByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
466    }
467
468    // For when we can get the EntityType from the EntityInstance:
469    public EntityAttribute getEntityAttribute(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance,
470            final EntityAttributeSpec spec, final EntityAttributeUuid uuid, final EntityPermission entityPermission,
471            final EntityAttributeTypes... entityAttributeTypes) {
472        EntityAttribute entityAttribute = null;
473        var entityAttributeName = spec.getEntityAttributeName();
474        var entityAttributeUuid = uuid.getEntityAttributeUuid();
475        var parameterCount = (entityAttributeName == null ? 0 : 1) + (entityAttributeUuid == null ? 0 : 1);
476
477        if (parameterCount == 1) {
478            entityAttribute = entityAttributeName == null
479                    ? getEntityAttributeByUuid(eea, entityAttributeUuid, entityPermission)
480                    : getEntityAttributeByName(eea, entityInstance.getEntityType(), entityAttributeName, entityPermission);
481        } else {
482            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
483        }
484
485        // If there are no other errors, and the EntityAttribute was specified by ULID, then verify the EntityType...
486        if((eea == null || !eea.hasExecutionErrors()) && entityAttributeUuid != null) {
487            if(!entityInstance.getEntityType().equals(entityAttribute.getLastDetail().getEntityType())) {
488                var expectedEntityTypeDetail = entityAttribute.getLastDetail().getEntityType().getLastDetail();
489                var suppliedEntityTypeDetail = entityInstance.getEntityType().getLastDetail();
490
491                handleExecutionError(MismatchedEntityTypeException.class, eea, ExecutionErrors.MismatchedEntityType.name(),
492                        expectedEntityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
493                        expectedEntityTypeDetail.getEntityTypeName(),
494                        suppliedEntityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
495                        suppliedEntityTypeDetail.getEntityTypeName());
496            }
497        }
498
499        // If there are no other errors, and there are one of more entityAttributeTypes specified, then verify the EntityAttributeType...
500        if((eea == null || !eea.hasExecutionErrors()) && entityAttributeTypes.length > 0) {
501            var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName();
502            var found = false;
503
504            for(var entityAttributeType : entityAttributeTypes) {
505                if(entityAttributeTypeName.equals(entityAttributeType.name())) {
506                    found = true;
507                    break;
508                }
509            }
510
511            if(!found) {
512                handleExecutionError(MismatchedEntityAttributeTypeException.class, eea, ExecutionErrors.MismatchedEntityAttributeType.name(),
513                        entityAttributeTypeName);
514                entityAttribute = null;
515            }
516        }
517
518        return entityAttribute;
519    }
520
521    public EntityAttribute getEntityAttribute(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance,
522            final EntityAttributeSpec spec, final EntityAttributeUuid uuid, final EntityAttributeTypes... entityAttributeTypes) {
523        return getEntityAttribute(eea, entityInstance, spec, uuid, EntityPermission.READ_ONLY, entityAttributeTypes);
524    }
525
526    public EntityAttribute getEntityAttributeForUpdate(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance,
527            final EntityAttributeSpec spec, final EntityAttributeUuid uuid, final EntityAttributeTypes... entityAttributeTypes) {
528        return getEntityAttribute(eea, entityInstance, spec, uuid, EntityPermission.READ_WRITE, entityAttributeTypes);
529    }
530
531    public EntityInstance getEntityInstanceAttribute(final ExecutionErrorAccumulator eea,
532            final EntityInstanceAttributeSpec entityInstanceAttributeSpec) {
533        var entityRef = entityInstanceAttributeSpec.getEntityRefAttribute();
534        var uuid = entityInstanceAttributeSpec.getUuidAttribute();
535
536        return EntityInstanceLogic.getInstance().getEntityInstance(eea, entityRef, uuid, null);
537    }
538
539    private List<EntityInstancePKResult> getEntityInstanceResultsByEntityAttributeTypeName(EntityAttribute entityAttribute) {
540        List<EntityInstancePKResult> entityInstanceResults = null;
541        var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName();
542        
543        if(entityAttributeTypeName.equals(EntityAttributeTypes.BOOLEAN.name())) {
544            entityInstanceResults = new EntityInstancePKsByBooleanEntityAttributeQuery().execute(entityAttribute);
545        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.NAME.name())) {
546            entityInstanceResults = new EntityInstancePKsByNameEntityAttributeQuery().execute(entityAttribute);
547        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.INTEGER.name())) {
548            entityInstanceResults = new EntityInstancePKsByIntegerEntityAttributeQuery().execute(entityAttribute);
549        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.LONG.name())) {
550            entityInstanceResults = new EntityInstancePKsByLongEntityAttributeQuery().execute(entityAttribute);
551        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.STRING.name())) {
552            entityInstanceResults = new EntityInstancePKsByStringEntityAttributeQuery().execute(entityAttribute);
553        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.GEOPOINT.name())) {
554            entityInstanceResults = new EntityInstancePKsByGeoPointEntityAttributeQuery().execute(entityAttribute);
555        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.BLOB.name())) {
556            entityInstanceResults = new EntityInstancePKsByBlobEntityAttributeQuery().execute(entityAttribute);
557        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.CLOB.name())) {
558            entityInstanceResults = new EntityInstancePKsByClobEntityAttributeQuery().execute(entityAttribute);
559        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.DATE.name())) {
560            entityInstanceResults = new EntityInstancePKsByDateEntityAttributeQuery().execute(entityAttribute);
561        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.TIME.name())) {
562            entityInstanceResults = new EntityInstancePKsByTimeEntityAttributeQuery().execute(entityAttribute);
563        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name())) {
564            entityInstanceResults = new EntityInstancePKsByListItemEntityAttributeQuery().execute(entityAttribute);
565        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name())) {
566            entityInstanceResults = new EntityInstancePKsByMultipleListItemEntityAttributeQuery().execute(entityAttribute);
567        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.ENTITY.name())) {
568            entityInstanceResults = new EntityInstancePKsByEntityEntityAttributeQuery().execute(entityAttribute);
569        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.COLLECTION.name())) {
570            entityInstanceResults = new EntityInstancePKsByCollectionEntityAttributeQuery().execute(entityAttribute);
571        }
572
573        return entityInstanceResults;
574    }
575    
576    public void updateEntityAttributeFromValue(final Session session, final EntityAttributeDetailValue entityAttributeDetailValue,
577            final BasePK updatedBy) {
578        if(entityAttributeDetailValue.getEntityAttributeNameHasBeenModified()) {
579            final var indexControl = Session.getModelController(IndexControl.class);
580            final var entityAttribute = coreControl.getEntityAttributeByPK(entityAttributeDetailValue.getEntityAttributePK());
581            
582            if(indexControl.countIndexTypesByEntityType(entityAttribute.getLastDetail().getEntityType()) > 0) {
583                final var queueControl = Session.getModelController(QueueControl.class);
584                final var queueTypePK = QueueTypeLogic.getInstance().getQueueTypeByName(null, QueueTypes.INDEXING.name()).getPrimaryKey();
585                final var entityInstanceResults = getEntityInstanceResultsByEntityAttributeTypeName(entityAttribute);
586                final var queuedEntities = new ArrayList<QueuedEntityValue>(entityInstanceResults.size());
587
588                for(final var entityInstanceResult : entityInstanceResults) {
589                    queuedEntities.add(new QueuedEntityValue(queueTypePK, entityInstanceResult.getEntityInstancePK(), session.START_TIME_LONG));
590                }
591
592                queueControl.createQueuedEntities(queuedEntities);
593            }
594        }
595        
596        coreControl.updateEntityAttributeFromValue(entityAttributeDetailValue, updatedBy);
597    }
598    
599    public void deleteEntityAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
600            final PartyPK deletedByPK) {
601        coreControl.deleteEntityAttribute(entityAttribute, deletedByPK);
602    }
603
604    public EntityListItem createEntityListItem(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
605            String entityListItemName, final Boolean isDefault, final Integer sortOrder, final BasePK createdBy,
606            final Language language, final String description) {
607        EntityListItem entityListItem = null;
608        var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName();
609
610        if(entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name())
611                || entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name())) {
612            if(entityListItemName == null) {
613                var entityAttributeListItem = coreControl.getEntityAttributeListItem(entityAttribute);
614                var entityListItemSequence = entityAttributeListItem == null ? null : entityAttributeListItem.getEntityListItemSequence();
615
616                if(entityListItemSequence == null) {
617                    entityListItemSequence = SequenceGeneratorLogic.getInstance().getDefaultSequence(eea, SequenceTypes.ENTITY_LIST_ITEM.name());
618                }
619
620                if(eea != null && !hasExecutionErrors(eea)) {
621                    entityListItemName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(eea, entityListItemSequence);
622                } else {
623                    handleExecutionError(MissingDefaultSequenceException.class, eea, ExecutionErrors.MissingDefaultSequence.name(),
624                            SequenceTypes.ENTITY_LIST_ITEM.name());
625                }
626            }
627            
628            if(eea != null && !hasExecutionErrors(eea)) {
629                entityListItem = entityListItemName == null ? null : coreControl.getEntityListItemByName(entityAttribute, entityListItemName);
630
631                if(entityListItem == null) {
632                    entityListItem = coreControl.createEntityListItem(entityAttribute, entityListItemName, isDefault, sortOrder,
633                            createdBy);
634
635                    if(description != null) {
636                        coreControl.createEntityListItemDescription(entityListItem, language, description, createdBy);
637                    }
638                } else {
639                    var entityAttributeDetail = entityAttribute.getLastDetail();
640                    var entityTypeDetail = entityAttributeDetail.getEntityType().getLastDetail();
641                    
642                    handleExecutionError(DuplicateEntityListItemNameException.class, eea, ExecutionErrors.DuplicateEntityListItemName.name(),
643                            entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
644                            entityTypeDetail.getEntityTypeName(), entityAttributeDetail.getEntityAttributeName(),
645                            entityListItemName);
646                }
647            }
648        } else {
649            var entityAttributeDetail = entityAttribute.getLastDetail();
650            var entityTypeDetail = entityAttributeDetail.getEntityType().getLastDetail();
651                    
652            handleExecutionError(InvalidEntityAttributeTypeException.class, eea, ExecutionErrors.InvalidEntityAttributeType.name(), 
653                            entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
654                            entityTypeDetail.getEntityTypeName(), entityAttributeDetail.getEntityAttributeName(),
655                            entityAttributeTypeName);
656        }
657        
658        return entityListItem;
659    }
660    
661    public EntityListItem getEntityListItemByName(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
662            final String entityListItemName, final EntityPermission entityPermission) {
663        var entityListItem = coreControl.getEntityListItemByName(entityAttribute, entityListItemName, entityPermission);
664
665        if(entityListItem == null) {
666            var entityAttributeDetail = entityAttribute.getLastDetail();
667            var entityTypeDetail = entityAttributeDetail.getEntityType().getLastDetail();
668            
669            handleExecutionError(UnknownEntityListItemNameException.class, eea, ExecutionErrors.UnknownEntityListItemName.name(),
670                    entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
671                    entityTypeDetail.getEntityTypeName(), entityListItemName);
672        }
673
674        return entityListItem;
675    }
676
677    public EntityListItem getEntityListItemByName(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
678            final String entityListItemName) {
679        return getEntityListItemByName(eea, entityAttribute, entityListItemName, EntityPermission.READ_ONLY);
680    }
681    
682    public EntityListItem getEntityListItemByNameForUpdate(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
683            final String entityListItemName) {
684        return getEntityListItemByName(eea, entityAttribute, entityListItemName, EntityPermission.READ_WRITE);
685    }
686        
687    public EntityListItem getEntityListItemByName(final ExecutionErrorAccumulator eea, final String componentVendorName,
688            final String entityTypeName, final String entityAttributeName, final String entityListItemName,
689            final EntityPermission entityPermission) {
690        var entityAttribute = EntityAttributeLogic.getInstance().getEntityAttributeByName(eea, componentVendorName,
691                entityTypeName, entityAttributeName);
692        EntityListItem entityListItem = null;
693        
694        if(eea == null || !eea.hasExecutionErrors()) {
695            entityListItem = getEntityListItemByName(eea, entityAttribute, entityListItemName, entityPermission);
696        }
697
698        return entityListItem;
699    }
700    
701    public EntityListItem getEntityListItemByName(final ExecutionErrorAccumulator eea, final String componentVendorName,
702            final String entityTypeName, final String entityAttributeName, final String entityListItemName) {
703        return getEntityListItemByName(eea, componentVendorName, entityTypeName, entityAttributeName, entityListItemName,
704                EntityPermission.READ_ONLY);
705    }
706    
707    public EntityListItem getEntityListItemByNameForUpdate(final ExecutionErrorAccumulator eea, final String componentVendorName,
708            final String entityTypeName, final String entityAttributeName, final String entityListItemName) {
709        return getEntityListItemByName(eea, componentVendorName, entityTypeName, entityAttributeName, entityListItemName,
710                EntityPermission.READ_WRITE);
711    }
712        
713    public EntityListItem getEntityListItemByUuid(final ExecutionErrorAccumulator eea, final String uuid, final EntityPermission entityPermission) {
714        EntityListItem entityListItem = null;
715        
716        var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, (String)null, uuid,
717                ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityListItem.name());
718
719        if(eea == null || !eea.hasExecutionErrors()) {
720            entityListItem = coreControl.getEntityListItemByEntityInstance(entityInstance, entityPermission);
721        }
722
723        return entityListItem;
724    }
725    
726    public EntityListItem getEntityListItemByUuid(final ExecutionErrorAccumulator eea, final String uuid) {
727        return getEntityListItemByUuid(eea, uuid, EntityPermission.READ_ONLY);
728    }
729    
730    public EntityListItem getEntityListItemByUuidForUpdate(final ExecutionErrorAccumulator eea, final String uuid) {
731        return getEntityListItemByUuid(eea, uuid, EntityPermission.READ_WRITE);
732    }
733
734    public EntityListItem getEntityListItemByUniversalSpec(final ExecutionErrorAccumulator eea, final EntityListItemUniversalSpec universalSpec,
735            final EntityPermission entityPermission) {
736        EntityListItem entityListItem = null;
737        var componentVendorName = universalSpec.getComponentVendorName();
738        var entityTypeName = universalSpec.getEntityTypeName();
739        var entityAttributeName = universalSpec.getEntityAttributeName();
740        var entityListItemName = universalSpec.getEntityListItemName();
741        var universalSpecCount = EntityInstanceLogic.getInstance().countPossibleEntitySpecs(universalSpec);
742        var parameterCount = (componentVendorName == null && entityTypeName == null && entityAttributeName == null && entityListItemName == null ? 0 : 1)
743                + universalSpecCount;
744
745        switch(parameterCount) {
746            case 1 -> {
747                if(universalSpecCount == 1) {
748                    var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(eea, universalSpec,
749                            ComponentVendors.ECHO_THREE.name(), EntityTypes.EntityListItem.name());
750
751                    if(!eea.hasExecutionErrors()) {
752                        entityListItem = coreControl.getEntityListItemByEntityInstance(entityInstance, entityPermission);
753                    }
754                } else {
755                    entityListItem = getEntityListItemByName(eea, componentVendorName, entityTypeName, entityAttributeName,
756                            entityListItemName, entityPermission);
757                }
758            }
759            default -> {
760                handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
761            }
762        }
763
764        return entityListItem;
765    }
766
767    public EntityListItem getEntityListItemByUniversalSpec(final ExecutionErrorAccumulator eea, final EntityListItemUniversalSpec universalSpec) {
768        return getEntityListItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_ONLY);
769    }
770
771    public EntityListItem getEntityListItemByUniversalSpecForUpdate(final ExecutionErrorAccumulator eea, final EntityListItemUniversalSpec universalSpec) {
772        return getEntityListItemByUniversalSpec(eea, universalSpec, EntityPermission.READ_WRITE);
773    }
774
775    public EntityListItem getEntityListItem(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
776            final EntityListItemAttributeEdit edit, final EntityPermission entityPermission) {
777        EntityListItem entityListItem = null;
778        var entityListItemName = edit.getEntityListItemName();
779        var entityListItemUuid = edit.getEntityListItemUuid();
780        var parameterCount = (entityListItemName == null ? 0 : 1) + (entityListItemUuid == null ? 0 : 1);
781
782        if (parameterCount == 1) {
783            entityListItem = entityListItemName == null
784                    ? getEntityListItemByUuid(eea, entityListItemUuid, entityPermission)
785                    : getEntityListItemByName(eea, entityAttribute, entityListItemName, entityPermission);
786        } else {
787            handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name());
788        }
789        
790        if((eea == null || !eea.hasExecutionErrors()) && entityListItemUuid != null) {
791            var foundEntityAttribute = entityListItem.getLastDetail().getEntityAttribute();
792
793            if(!foundEntityAttribute.equals(entityAttribute)) {
794                handleExecutionError(MismatchedEntityListItemException.class, eea, ExecutionErrors.MismatchedEntityListItem.name(),
795                        entityAttribute.getLastDetail().getEntityType().getLastDetail().getComponentVendor().getLastDetail().getComponentVendorName(),
796                        entityAttribute.getLastDetail().getEntityType().getLastDetail().getEntityTypeName(),
797                        entityAttribute.getLastDetail().getEntityAttributeName(),
798                        foundEntityAttribute.getLastDetail().getEntityType().getLastDetail().getComponentVendor().getLastDetail().getComponentVendorName(),
799                        foundEntityAttribute.getLastDetail().getEntityType().getLastDetail().getEntityTypeName(),
800                        foundEntityAttribute.getLastDetail().getEntityAttributeName(),
801                        entityListItem.getLastDetail().getEntityListItem());
802            }
803        }
804        
805        return entityListItem;
806    }
807    
808    public EntityListItem getEntityListItem(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
809            final EntityListItemAttributeEdit edit) {
810        return getEntityListItem(eea, entityAttribute, edit, EntityPermission.READ_ONLY);
811    }
812    
813    public EntityListItem getEntityListItemForUpdate(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
814            final EntityListItemAttributeEdit edit, final EntityListItemUuid uuid) {
815        return getEntityListItem(eea, entityAttribute, edit, EntityPermission.READ_WRITE);
816    }
817    
818    public void updateEntityListItemFromValue(final Session session, EntityListItemDetailValue entityListItemDetailValue, BasePK updatedBy) {
819        if(entityListItemDetailValue.getEntityListItemNameHasBeenModified()) {
820            var indexControl = Session.getModelController(IndexControl.class);
821            var entityListItem = coreControl.getEntityListItemByPK(entityListItemDetailValue.getEntityListItemPK());
822            var entityAttributeDetail = entityListItem.getLastDetail().getEntityAttribute().getLastDetail();
823            
824            if(indexControl.countIndexTypesByEntityType(entityAttributeDetail.getEntityType()) > 0) {
825                var queueControl = Session.getModelController(QueueControl.class);
826                var queueTypePK = QueueTypeLogic.getInstance().getQueueTypeByName(null, QueueTypes.INDEXING.name()).getPrimaryKey();
827                var entityAttributeTypeName = entityAttributeDetail.getEntityAttributeType().getEntityAttributeTypeName();
828
829                if(entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name())) {
830                    var entityListItemAttributes = coreControl.getEntityListItemAttributesByEntityListItem(entityListItem);
831                    List<QueuedEntityValue> queuedEntities = new ArrayList<>(entityListItemAttributes.size());
832
833                    entityListItemAttributes.forEach((entityListItemAttribute) -> {
834                        queuedEntities.add(new QueuedEntityValue(queueTypePK, entityListItemAttribute.getEntityInstancePK(), session.START_TIME_LONG));
835                    });
836
837                    queueControl.createQueuedEntities(queuedEntities);
838                } else if(entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name())) {
839                    var entityMultipleListItemAttributes = coreControl.getEntityMultipleListItemAttributesByEntityListItem(entityListItem);
840                    List<QueuedEntityValue> queuedEntities = new ArrayList<>(entityMultipleListItemAttributes.size());
841
842                    entityMultipleListItemAttributes.forEach((entityMultipleListItemAttribute) -> {
843                        queuedEntities.add(new QueuedEntityValue(queueTypePK, entityMultipleListItemAttribute.getEntityInstancePK(), session.START_TIME_LONG));
844                    });
845
846                    queueControl.createQueuedEntities(queuedEntities);
847                }
848            }
849        }
850
851        coreControl.updateEntityListItemFromValue(entityListItemDetailValue, updatedBy);
852    }
853    
854    public void deleteEntityListItem(final ExecutionErrorAccumulator eea, EntityListItem entityListItem, BasePK deletedBy) {
855        coreControl.deleteEntityListItem(entityListItem, deletedBy);
856    }
857
858    private void checkEntityType(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
859            final EntityInstance entityInstance) {
860        if(!entityInstance.getEntityType().equals(entityAttribute.getLastDetail().getEntityType())) {
861            var expectedEntityTypeDetail = entityAttribute.getLastDetail().getEntityType().getLastDetail();
862            var suppliedEntityTypeDetail = entityInstance.getEntityType().getLastDetail();
863
864            handleExecutionError(MismatchedEntityTypeException.class, eea, ExecutionErrors.MismatchedEntityType.name(),
865                    expectedEntityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
866                    expectedEntityTypeDetail.getEntityTypeName(),
867                    suppliedEntityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
868                    suppliedEntityTypeDetail.getEntityTypeName());
869        }
870    }
871
872    private void checkEntityType(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
873            final EntityAttributeTypes entityAttributeType) {
874        var entityAttributeTypeName = entityAttributeType.name();
875
876        if(!entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName().equals(entityAttributeTypeName)) {
877            var expectedEntityTypeDetail = entityAttribute.getLastDetail().getEntityType().getLastDetail();
878
879            handleExecutionError(MismatchedEntityAttributeTypeException.class, eea, ExecutionErrors.MismatchedEntityAttributeType.name(),
880                    expectedEntityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
881                    expectedEntityTypeDetail.getEntityTypeName(),
882                    entityAttributeTypeName);
883        }
884    }
885
886    public EntityBooleanDefault createEntityBooleanDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
887            final Boolean booleanAttribute, final boolean addMissingAttributes, final BasePK createdBy) {
888        EntityBooleanDefault entityBooleanDefault = null;
889
890        checkEntityType(eea, entityAttribute, EntityAttributeTypes.BOOLEAN);
891
892        if(eea == null || !eea.hasExecutionErrors()) {
893            entityBooleanDefault = coreControl.getEntityBooleanDefault(entityAttribute);
894
895            if(entityBooleanDefault == null) {
896                coreControl.createEntityBooleanDefault(entityAttribute, booleanAttribute, createdBy);
897
898                if(addMissingAttributes) {
899                    new EntityInstancesMissingBooleanEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
900                            coreControl.createEntityBooleanAttribute(entityAttribute.getPrimaryKey(),
901                                    entityInstanceResult.getEntityInstance(), booleanAttribute, createdBy));
902                }
903            } else {
904                handleExecutionError(DuplicateEntityBooleanDefaultException.class, eea, ExecutionErrors.DuplicateEntityBooleanDefault.name(),
905                        entityAttribute.getLastDetail().getEntityAttributeName());
906            }
907        }
908
909        return entityBooleanDefault;
910    }
911
912    public void deleteEntityBooleanDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
913            final BasePK deletedBy) {
914        checkEntityType(eea, entityAttribute, EntityAttributeTypes.BOOLEAN);
915
916        if(eea == null || !eea.hasExecutionErrors()) {
917            var entityBooleanDefault = coreControl.getEntityBooleanDefaultForUpdate(entityAttribute);
918
919            if(entityBooleanDefault == null) {
920                handleExecutionError(UnknownEntityBooleanDefaultException.class, eea, ExecutionErrors.UnknownEntityBooleanDefault.name(),
921                        entityAttribute.getLastDetail().getEntityAttributeName());
922            } else {
923                coreControl.deleteEntityBooleanDefault(entityBooleanDefault, deletedBy);
924            }
925        }
926    }
927
928    public EntityBooleanAttribute createEntityBooleanAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
929            final EntityInstance entityInstance, final Boolean booleanAttribute, final BasePK createdBy) {
930        EntityBooleanAttribute entityBooleanAttribute = null;
931
932        checkEntityType(eea, entityAttribute, entityInstance);
933
934        if(eea == null || !eea.hasExecutionErrors()) {
935            entityBooleanAttribute = coreControl.getEntityBooleanAttribute(entityAttribute, entityInstance);
936
937            if(entityBooleanAttribute == null) {
938                coreControl.createEntityBooleanAttribute(entityAttribute, entityInstance, booleanAttribute, createdBy);
939            } else {
940                handleExecutionError(DuplicateEntityBooleanAttributeException.class, eea, ExecutionErrors.DuplicateEntityBooleanAttribute.name(),
941                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
942                        entityAttribute.getLastDetail().getEntityAttributeName());
943            }
944        }
945
946        return entityBooleanAttribute;
947    }
948
949    public EntityIntegerDefault createEntityIntegerDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
950            final Integer integerAttribute, final boolean addMissingAttributes, final BasePK createdBy) {
951        EntityIntegerDefault entityIntegerDefault = null;
952
953        checkEntityType(eea, entityAttribute, EntityAttributeTypes.INTEGER);
954
955        if(eea == null || !eea.hasExecutionErrors()) {
956            var entityAttributeInteger = coreControl.getEntityAttributeInteger(entityAttribute);
957
958            if(entityAttributeInteger != null) {
959                var upperRangeIntegerValue = entityAttributeInteger.getUpperRangeIntegerValue();
960                var lowerRangeIntegerValue = entityAttributeInteger.getLowerRangeIntegerValue();
961
962                if(upperRangeIntegerValue != null && integerAttribute > upperRangeIntegerValue){
963                    handleExecutionError(UpperRangeExceededException.class, eea, ExecutionErrors.UpperRangeExceeded.name(),
964                            upperRangeIntegerValue, integerAttribute);
965                }
966
967                if(lowerRangeIntegerValue != null && integerAttribute < lowerRangeIntegerValue) {
968                    handleExecutionError(LowerRangeExceededException.class, eea, ExecutionErrors.LowerRangeExceeded.name(),
969                            lowerRangeIntegerValue, integerAttribute);
970                }
971            }
972
973            if(eea == null || !eea.hasExecutionErrors()) {
974                entityIntegerDefault = coreControl.getEntityIntegerDefault(entityAttribute);
975
976                if(entityIntegerDefault == null) {
977                    coreControl.createEntityIntegerDefault(entityAttribute, integerAttribute, createdBy);
978
979                    if(addMissingAttributes) {
980                        new EntityInstancesMissingIntegerEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
981                                coreControl.createEntityIntegerAttribute(entityAttribute.getPrimaryKey(),
982                                        entityInstanceResult.getEntityInstance(), integerAttribute, createdBy));
983                    }
984                } else {
985                    handleExecutionError(DuplicateEntityIntegerDefaultException.class, eea, ExecutionErrors.DuplicateEntityIntegerDefault.name(),
986                            entityAttribute.getLastDetail().getEntityAttributeName());
987                }
988            }
989        }
990
991        return entityIntegerDefault;
992    }
993
994    public void deleteEntityIntegerDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
995            final BasePK deletedBy) {
996        checkEntityType(eea, entityAttribute, EntityAttributeTypes.INTEGER);
997
998        if(eea == null || !eea.hasExecutionErrors()) {
999            var entityIntegerDefault = coreControl.getEntityIntegerDefaultForUpdate(entityAttribute);
1000
1001            if(entityIntegerDefault == null) {
1002                handleExecutionError(UnknownEntityIntegerDefaultException.class, eea, ExecutionErrors.UnknownEntityIntegerDefault.name(),
1003                        entityAttribute.getLastDetail().getEntityAttributeName());
1004            } else {
1005                coreControl.deleteEntityIntegerDefault(entityIntegerDefault, deletedBy);
1006            }
1007        }
1008    }
1009
1010    public EntityIntegerAttribute createEntityIntegerAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1011            final EntityInstance entityInstance, final Integer integerAttribute, final BasePK createdBy) {
1012        EntityIntegerAttribute entityIntegerAttribute = null;
1013        
1014        checkEntityType(eea, entityAttribute, entityInstance);
1015        
1016        if(eea == null || !eea.hasExecutionErrors()) {
1017            var entityAttributeInteger = coreControl.getEntityAttributeInteger(entityAttribute);
1018            
1019            if(entityAttributeInteger != null) {
1020                var upperRangeIntegerValue = entityAttributeInteger.getUpperRangeIntegerValue();
1021                var lowerRangeIntegerValue = entityAttributeInteger.getLowerRangeIntegerValue();
1022                
1023                if(upperRangeIntegerValue != null && integerAttribute > upperRangeIntegerValue){
1024                    handleExecutionError(UpperRangeExceededException.class, eea, ExecutionErrors.UpperRangeExceeded.name(),
1025                            upperRangeIntegerValue, integerAttribute);
1026                }
1027                
1028                if(lowerRangeIntegerValue != null && integerAttribute < lowerRangeIntegerValue) {
1029                    handleExecutionError(LowerRangeExceededException.class, eea, ExecutionErrors.LowerRangeExceeded.name(),
1030                            lowerRangeIntegerValue, integerAttribute);
1031                }
1032            }
1033            
1034            if(eea == null || !eea.hasExecutionErrors()) {
1035                entityIntegerAttribute = coreControl.getEntityIntegerAttribute(entityAttribute, entityInstance);
1036
1037                if(entityIntegerAttribute == null) {
1038                    coreControl.createEntityIntegerAttribute(entityAttribute, entityInstance, integerAttribute, createdBy);
1039                } else {
1040                    handleExecutionError(DuplicateEntityIntegerAttributeException.class, eea, ExecutionErrors.DuplicateEntityIntegerAttribute.name(),
1041                            EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1042                            entityAttribute.getLastDetail().getEntityAttributeName());
1043                }
1044            }
1045        }
1046
1047        return entityIntegerAttribute;
1048    }
1049
1050    public EntityLongDefault createEntityLongDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1051            final Long longAttribute, final boolean addMissingAttributes, BasePK createdBy) {
1052        EntityLongDefault entityLongDefault = null;
1053
1054        checkEntityType(eea, entityAttribute, EntityAttributeTypes.LONG);
1055
1056        if(eea == null || !eea.hasExecutionErrors()) {
1057            var entityAttributeLong = coreControl.getEntityAttributeLong(entityAttribute);
1058
1059            if(entityAttributeLong != null) {
1060                var upperRangeLongValue = entityAttributeLong.getUpperRangeLongValue();
1061                var lowerRangeLongValue = entityAttributeLong.getLowerRangeLongValue();
1062
1063                if(upperRangeLongValue != null && longAttribute > upperRangeLongValue){
1064                    handleExecutionError(UpperRangeExceededException.class, eea, ExecutionErrors.UpperRangeExceeded.name(),
1065                            upperRangeLongValue, longAttribute);
1066                }
1067
1068                if(lowerRangeLongValue != null && longAttribute < lowerRangeLongValue) {
1069                    handleExecutionError(LowerRangeExceededException.class, eea, ExecutionErrors.LowerRangeExceeded.name(),
1070                            lowerRangeLongValue, longAttribute);
1071                }
1072            }
1073
1074            if(eea == null || !eea.hasExecutionErrors()) {
1075                entityLongDefault = coreControl.getEntityLongDefault(entityAttribute);
1076
1077                if(entityLongDefault == null) {
1078                    coreControl.createEntityLongDefault(entityAttribute, longAttribute, createdBy);
1079
1080                    if(addMissingAttributes) {
1081                        new EntityInstancesMissingLongEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
1082                                coreControl.createEntityLongAttribute(entityAttribute.getPrimaryKey(),
1083                                        entityInstanceResult.getEntityInstance(), longAttribute, createdBy));
1084                    }
1085                } else {
1086                    handleExecutionError(DuplicateEntityLongDefaultException.class, eea, ExecutionErrors.DuplicateEntityLongDefault.name(),
1087                            entityAttribute.getLastDetail().getEntityAttributeName());
1088                }
1089            }
1090        }
1091
1092        return entityLongDefault;
1093    }
1094
1095    public void deleteEntityLongDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1096            final BasePK deletedBy) {
1097        checkEntityType(eea, entityAttribute, EntityAttributeTypes.LONG);
1098
1099        if(eea == null || !eea.hasExecutionErrors()) {
1100            var entityLongDefault = coreControl.getEntityLongDefaultForUpdate(entityAttribute);
1101
1102            if(entityLongDefault == null) {
1103                handleExecutionError(UnknownEntityLongDefaultException.class, eea, ExecutionErrors.UnknownEntityLongDefault.name(),
1104                        entityAttribute.getLastDetail().getEntityAttributeName());
1105            } else {
1106                coreControl.deleteEntityLongDefault(entityLongDefault, deletedBy);
1107            }
1108        }
1109    }
1110
1111    public EntityLongAttribute createEntityLongAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1112            final EntityInstance entityInstance, final Long longAttribute, final BasePK createdBy) {
1113        EntityLongAttribute entityLongAttribute = null;
1114        
1115        checkEntityType(eea, entityAttribute, entityInstance);
1116        
1117        if(eea == null || !eea.hasExecutionErrors()) {
1118            var entityAttributeLong = coreControl.getEntityAttributeLong(entityAttribute);
1119            
1120            if(entityAttributeLong != null) {
1121                var upperRangeLongValue = entityAttributeLong.getUpperRangeLongValue();
1122                var lowerRangeLongValue = entityAttributeLong.getLowerRangeLongValue();
1123                
1124                if(upperRangeLongValue != null && longAttribute > upperRangeLongValue){
1125                    handleExecutionError(UpperRangeExceededException.class, eea, ExecutionErrors.UpperRangeExceeded.name(),
1126                            upperRangeLongValue, longAttribute);
1127                }
1128                
1129                if(lowerRangeLongValue != null && longAttribute < lowerRangeLongValue) {
1130                    handleExecutionError(LowerRangeExceededException.class, eea, ExecutionErrors.LowerRangeExceeded.name(),
1131                            lowerRangeLongValue, longAttribute);
1132                }
1133            }
1134            
1135            if(eea == null || !eea.hasExecutionErrors()) {
1136                entityLongAttribute = coreControl.getEntityLongAttribute(entityAttribute, entityInstance);
1137
1138                if(entityLongAttribute == null) {
1139                    coreControl.createEntityLongAttribute(entityAttribute, entityInstance, longAttribute, createdBy);
1140                } else {
1141                    handleExecutionError(DuplicateEntityLongAttributeException.class, eea, ExecutionErrors.DuplicateEntityLongAttribute.name(),
1142                            EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1143                            entityAttribute.getLastDetail().getEntityAttributeName());
1144                }
1145            }
1146        }
1147
1148        return entityLongAttribute;
1149    }
1150
1151    public EntityStringDefault createEntityStringDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1152            final Language language, final String stringAttribute, final boolean addMissingAttributes, final BasePK createdBy) {
1153        EntityStringDefault entityStringDefault = null;
1154
1155        checkEntityType(eea, entityAttribute, EntityAttributeTypes.STRING);
1156
1157        if(eea == null || !eea.hasExecutionErrors()) {
1158            entityStringDefault = coreControl.getEntityStringDefault(entityAttribute, language);
1159
1160            if(entityStringDefault == null) {
1161                coreControl.createEntityStringDefault(entityAttribute, language, stringAttribute, createdBy);
1162
1163                if(addMissingAttributes) {
1164                    new EntityInstancesMissingStringEntityAttributeQuery().execute(entityAttribute, language).forEach(entityInstanceResult ->
1165                            coreControl.createEntityStringAttribute(entityAttribute.getPrimaryKey(),
1166                                    entityInstanceResult.getEntityInstance(), language, stringAttribute, createdBy));
1167                }
1168            } else {
1169                handleExecutionError(DuplicateEntityStringDefaultException.class, eea, ExecutionErrors.DuplicateEntityStringDefault.name(),
1170                        entityAttribute.getLastDetail().getEntityAttributeName());
1171            }
1172        }
1173
1174        return entityStringDefault;
1175    }
1176
1177    public void deleteEntityStringDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1178            final Language language, final BasePK deletedBy) {
1179        checkEntityType(eea, entityAttribute, EntityAttributeTypes.STRING);
1180
1181        if(eea == null || !eea.hasExecutionErrors()) {
1182            var entityStringDefault = coreControl.getEntityStringDefaultForUpdate(entityAttribute, language);
1183
1184            if(entityStringDefault == null) {
1185                handleExecutionError(UnknownEntityStringDefaultException.class, eea, ExecutionErrors.UnknownEntityStringDefault.name(),
1186                        entityAttribute.getLastDetail().getEntityAttributeName(),
1187                        language.getLanguageIsoName());
1188            } else {
1189                coreControl.deleteEntityStringDefault(entityStringDefault, deletedBy);
1190            }
1191        }
1192    }
1193
1194    public EntityStringAttribute createEntityStringAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1195            final EntityInstance entityInstance, final Language language, final String stringAttribute, final BasePK createdBy) {
1196        EntityStringAttribute entityStringAttribute = null;
1197
1198        checkEntityType(eea, entityAttribute, entityInstance);
1199
1200        if(eea == null || !eea.hasExecutionErrors()) {
1201            var entityAttributeString = coreControl.getEntityAttributeString(entityAttribute);
1202            var validationPattern = entityAttributeString == null ? null : entityAttributeString.getValidationPattern();
1203
1204            if(validationPattern != null) {
1205                var pattern = Pattern.compile(validationPattern);
1206                var m = pattern.matcher(stringAttribute);
1207
1208                if(!m.matches()) {
1209                    handleExecutionError(InvalidStringAttributeException.class, eea, ExecutionErrors.InvalidStringAttribute.name(),
1210                            stringAttribute);
1211                }
1212            }
1213
1214            if(eea == null || !eea.hasExecutionErrors()) {
1215                entityStringAttribute = coreControl.getEntityStringAttribute(entityAttribute, entityInstance, language);
1216
1217                if(entityStringAttribute == null) {
1218                    coreControl.createEntityStringAttribute(entityAttribute, entityInstance, language, stringAttribute, createdBy);
1219                } else {
1220                    handleExecutionError(DuplicateEntityStringAttributeException.class, eea, ExecutionErrors.DuplicateEntityStringAttribute.name(),
1221                            EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1222                            entityAttribute.getLastDetail().getEntityAttributeName(),
1223                            language.getLanguageIsoName());
1224                }
1225            }
1226        }
1227
1228        return entityStringAttribute;
1229    }
1230
1231    public EntityClobAttribute createEntityClobAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1232            final EntityInstance entityInstance, final Language language, final String clobAttribute, final MimeType mimeType,
1233            final BasePK createdBy) {
1234        EntityClobAttribute entityClobAttribute = null;
1235
1236        checkEntityType(eea, entityAttribute, entityInstance);
1237
1238        if(eea == null || !eea.hasExecutionErrors()) {
1239            entityClobAttribute = coreControl.getEntityClobAttribute(entityAttribute, entityInstance, language);
1240
1241            if(entityClobAttribute == null) {
1242                coreControl.createEntityClobAttribute(entityAttribute, entityInstance, language, clobAttribute, mimeType, createdBy);
1243            } else {
1244                handleExecutionError(DuplicateEntityClobAttributeException.class, eea, ExecutionErrors.DuplicateEntityClobAttribute.name(),
1245                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1246                        entityAttribute.getLastDetail().getEntityAttributeName(),
1247                        language.getLanguageIsoName());
1248            }
1249        }
1250
1251        return entityClobAttribute;
1252    }
1253
1254    public EntityNameAttribute createEntityNameAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1255            final String nameAttribute, final EntityInstance entityInstance, final BasePK createdBy) {
1256        EntityNameAttribute entityNameAttribute = null;
1257
1258        checkEntityType(eea, entityAttribute, entityInstance);
1259
1260        if(eea == null || !eea.hasExecutionErrors()) {
1261            entityNameAttribute = coreControl.getEntityNameAttribute(entityAttribute, entityInstance);
1262
1263            if(entityNameAttribute == null) {
1264                coreControl.createEntityNameAttribute(entityAttribute, nameAttribute, entityInstance, createdBy);
1265            } else {
1266                handleExecutionError(DuplicateEntityNameAttributeException.class, eea, ExecutionErrors.DuplicateEntityNameAttribute.name(),
1267                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1268                        entityAttribute.getLastDetail().getEntityAttributeName());
1269            }
1270        }
1271
1272        return entityNameAttribute;
1273    }
1274
1275    public EntityDateDefault createEntityDateDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1276            final Integer dateAttribute, final boolean addMissingAttributes, BasePK createdBy) {
1277        EntityDateDefault entityDateDefault = null;
1278
1279        checkEntityType(eea, entityAttribute, EntityAttributeTypes.DATE);
1280
1281        if(eea == null || !eea.hasExecutionErrors()) {
1282            entityDateDefault = coreControl.getEntityDateDefault(entityAttribute);
1283
1284            if(entityDateDefault == null) {
1285                coreControl.createEntityDateDefault(entityAttribute, dateAttribute, createdBy);
1286
1287                if(addMissingAttributes) {
1288                    new EntityInstancesMissingDateEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
1289                            coreControl.createEntityDateAttribute(entityAttribute.getPrimaryKey(),
1290                                    entityInstanceResult.getEntityInstance(), dateAttribute, createdBy));
1291                }
1292            } else {
1293                handleExecutionError(DuplicateEntityDateDefaultException.class, eea, ExecutionErrors.DuplicateEntityDateDefault.name(),
1294                        entityAttribute.getLastDetail().getEntityAttributeName());
1295            }
1296        }
1297
1298        return entityDateDefault;
1299    }
1300
1301    public void deleteEntityDateDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1302            final BasePK deletedBy) {
1303        checkEntityType(eea, entityAttribute, EntityAttributeTypes.DATE);
1304
1305        if(eea == null || !eea.hasExecutionErrors()) {
1306            var entityDateDefault = coreControl.getEntityDateDefaultForUpdate(entityAttribute);
1307
1308            if(entityDateDefault == null) {
1309                handleExecutionError(UnknownEntityDateDefaultException.class, eea, ExecutionErrors.UnknownEntityDateDefault.name(),
1310                        entityAttribute.getLastDetail().getEntityAttributeName());
1311            } else {
1312                coreControl.deleteEntityDateDefault(entityDateDefault, deletedBy);
1313            }
1314        }
1315    }
1316
1317    public EntityDateAttribute createEntityDateAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1318            final EntityInstance entityInstance, final Integer dateAttribute, final BasePK createdBy) {
1319        EntityDateAttribute entityDateAttribute = null;
1320
1321        checkEntityType(eea, entityAttribute, entityInstance);
1322
1323        if(eea == null || !eea.hasExecutionErrors()) {
1324            entityDateAttribute = coreControl.getEntityDateAttribute(entityAttribute, entityInstance);
1325
1326            if(entityDateAttribute == null) {
1327                coreControl.createEntityDateAttribute(entityAttribute, entityInstance, dateAttribute, createdBy);
1328            } else {
1329                handleExecutionError(DuplicateEntityDateAttributeException.class, eea, ExecutionErrors.DuplicateEntityDateAttribute.name(),
1330                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1331                        entityAttribute.getLastDetail().getEntityAttributeName());
1332            }
1333        }
1334
1335        return entityDateAttribute;
1336    }
1337
1338    public EntityTimeDefault createEntityTimeDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1339            final Long timeAttribute, final boolean addMissingAttributes, BasePK createdBy) {
1340        EntityTimeDefault entityTimeDefault = null;
1341
1342        checkEntityType(eea, entityAttribute, EntityAttributeTypes.TIME);
1343
1344        if(eea == null || !eea.hasExecutionErrors()) {
1345            entityTimeDefault = coreControl.getEntityTimeDefault(entityAttribute);
1346
1347            if(entityTimeDefault == null) {
1348                coreControl.createEntityTimeDefault(entityAttribute, timeAttribute, createdBy);
1349
1350                if(addMissingAttributes) {
1351                    new EntityInstancesMissingTimeEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
1352                            coreControl.createEntityTimeAttribute(entityAttribute.getPrimaryKey(),
1353                                    entityInstanceResult.getEntityInstance(), timeAttribute, createdBy));
1354                }
1355            } else {
1356                handleExecutionError(DuplicateEntityTimeDefaultException.class, eea, ExecutionErrors.DuplicateEntityTimeDefault.name(),
1357                        entityAttribute.getLastDetail().getEntityAttributeName());
1358            }
1359        }
1360
1361        return entityTimeDefault;
1362    }
1363
1364    public void deleteEntityTimeDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1365            final BasePK deletedBy) {
1366        checkEntityType(eea, entityAttribute, EntityAttributeTypes.TIME);
1367
1368        if(eea == null || !eea.hasExecutionErrors()) {
1369            var entityTimeDefault = coreControl.getEntityTimeDefaultForUpdate(entityAttribute);
1370
1371            if(entityTimeDefault == null) {
1372                handleExecutionError(UnknownEntityTimeDefaultException.class, eea, ExecutionErrors.UnknownEntityTimeDefault.name(),
1373                        entityAttribute.getLastDetail().getEntityAttributeName());
1374            } else {
1375                coreControl.deleteEntityTimeDefault(entityTimeDefault, deletedBy);
1376            }
1377        }
1378    }
1379
1380    public EntityTimeAttribute createEntityTimeAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1381            final EntityInstance entityInstance, final Long timeAttribute, final BasePK createdBy) {
1382        EntityTimeAttribute entityTimeAttribute = null;
1383
1384        checkEntityType(eea, entityAttribute, entityInstance);
1385
1386        if(eea == null || !eea.hasExecutionErrors()) {
1387            entityTimeAttribute = coreControl.getEntityTimeAttribute(entityAttribute, entityInstance);
1388
1389            if(entityTimeAttribute == null) {
1390                coreControl.createEntityTimeAttribute(entityAttribute, entityInstance, timeAttribute, createdBy);
1391            } else {
1392                handleExecutionError(DuplicateEntityTimeAttributeException.class, eea, ExecutionErrors.DuplicateEntityTimeAttribute.name(),
1393                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1394                        entityAttribute.getLastDetail().getEntityAttributeName());
1395            }
1396        }
1397
1398        return entityTimeAttribute;
1399    }
1400
1401    public EntityGeoPointDefault createEntityGeoPointDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1402            final Integer latitude, final Integer longitude, final Long elevation, final Long altitude, final boolean addMissingAttributes, BasePK createdBy) {
1403        EntityGeoPointDefault entityGeoPointDefault = null;
1404
1405        checkEntityType(eea, entityAttribute, EntityAttributeTypes.GEOPOINT);
1406
1407        if(eea == null || !eea.hasExecutionErrors()) {
1408            entityGeoPointDefault = coreControl.getEntityGeoPointDefault(entityAttribute);
1409
1410            if(entityGeoPointDefault == null) {
1411                coreControl.createEntityGeoPointDefault(entityAttribute, latitude, longitude, elevation, altitude, createdBy);
1412
1413                if(addMissingAttributes) {
1414                    new EntityInstancesMissingGeoPointEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
1415                            coreControl.createEntityGeoPointAttribute(entityAttribute.getPrimaryKey(),
1416                                    entityInstanceResult.getEntityInstance(), latitude, longitude, elevation, altitude, createdBy));
1417                }
1418            } else {
1419                handleExecutionError(DuplicateEntityGeoPointDefaultException.class, eea, ExecutionErrors.DuplicateEntityGeoPointDefault.name(),
1420                        entityAttribute.getLastDetail().getEntityAttributeName());
1421            }
1422        }
1423
1424        return entityGeoPointDefault;
1425    }
1426
1427    public void deleteEntityGeoPointDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1428            final BasePK deletedBy) {
1429        checkEntityType(eea, entityAttribute, EntityAttributeTypes.GEOPOINT);
1430
1431        if(eea == null || !eea.hasExecutionErrors()) {
1432            var entityGeoPointDefault = coreControl.getEntityGeoPointDefaultForUpdate(entityAttribute);
1433
1434            if(entityGeoPointDefault == null) {
1435                handleExecutionError(UnknownEntityGeoPointDefaultException.class, eea, ExecutionErrors.UnknownEntityGeoPointDefault.name(),
1436                        entityAttribute.getLastDetail().getEntityAttributeName());
1437            } else {
1438                coreControl.deleteEntityGeoPointDefault(entityGeoPointDefault, deletedBy);
1439            }
1440        }
1441    }
1442
1443    public EntityGeoPointAttribute createEntityGeoPointAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1444            final EntityInstance entityInstance, final Integer latitude, final Integer longitude, final Long elevation, final Long altitude, final BasePK createdBy) {
1445        EntityGeoPointAttribute entityGeoPointAttribute = null;
1446
1447        checkEntityType(eea, entityAttribute, entityInstance);
1448
1449        if(eea == null || !eea.hasExecutionErrors()) {
1450            entityGeoPointAttribute = coreControl.getEntityGeoPointAttribute(entityAttribute, entityInstance);
1451
1452            if(entityGeoPointAttribute == null) {
1453                coreControl.createEntityGeoPointAttribute(entityAttribute, entityInstance, latitude, longitude, elevation, altitude, createdBy);
1454            } else {
1455                handleExecutionError(DuplicateEntityGeoPointAttributeException.class, eea, ExecutionErrors.DuplicateEntityGeoPointAttribute.name(),
1456                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1457                        entityAttribute.getLastDetail().getEntityAttributeName());
1458            }
1459        }
1460
1461        return entityGeoPointAttribute;
1462    }
1463
1464    public EntityListItemDefault createEntityListItemDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1465            final EntityListItem entityListItem, final boolean addMissingAttributes, final BasePK createdBy) {
1466        EntityListItemDefault entityListItemDefault = null;
1467
1468        checkEntityType(eea, entityAttribute, EntityAttributeTypes.LISTITEM);
1469
1470        if(eea == null || !eea.hasExecutionErrors()) {
1471            entityListItemDefault = coreControl.getEntityListItemDefault(entityAttribute);
1472
1473            if(entityListItemDefault == null) {
1474                coreControl.createEntityListItemDefault(entityAttribute, entityListItem, createdBy);
1475
1476                if(addMissingAttributes) {
1477                    new EntityInstancesMissingListItemEntityAttributeQuery().execute(entityAttribute).forEach(entityInstanceResult ->
1478                            coreControl.createEntityListItemAttribute(entityAttribute.getPrimaryKey(),
1479                                    entityInstanceResult.getEntityInstance(), entityListItem, createdBy));
1480                }
1481            } else {
1482                handleExecutionError(DuplicateEntityListItemDefaultException.class, eea, ExecutionErrors.DuplicateEntityListItemDefault.name(),
1483                        entityAttribute.getLastDetail().getEntityAttributeName());
1484            }
1485        }
1486
1487        return entityListItemDefault;
1488    }
1489
1490    public void deleteEntityListItemDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1491            final BasePK deletedBy) {
1492        checkEntityType(eea, entityAttribute, EntityAttributeTypes.LISTITEM);
1493
1494        if(eea == null || !eea.hasExecutionErrors()) {
1495            var entityListItemDefault = coreControl.getEntityListItemDefaultForUpdate(entityAttribute);
1496
1497            if(entityListItemDefault == null) {
1498                handleExecutionError(UnknownEntityListItemDefaultException.class, eea, ExecutionErrors.UnknownEntityListItemDefault.name(),
1499                        entityAttribute.getLastDetail().getEntityAttributeName());
1500            } else {
1501                coreControl.deleteEntityListItemDefault(entityListItemDefault, deletedBy);
1502            }
1503        }
1504    }
1505
1506    public EntityListItemAttribute createEntityListItemAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1507        final EntityInstance entityInstance, final EntityListItem entityListItem, final BasePK createdBy) {
1508        EntityListItemAttribute entityListItemAttribute = null;
1509        
1510        checkEntityType(eea, entityAttribute, entityInstance);
1511        
1512        if(eea == null || !eea.hasExecutionErrors()) {
1513            entityListItemAttribute = coreControl.getEntityListItemAttribute(entityAttribute, entityInstance);
1514
1515            if(entityListItemAttribute == null) {
1516                entityListItemAttribute = coreControl.createEntityListItemAttribute(entityAttribute, entityInstance, entityListItem, createdBy);
1517            } else {
1518                handleExecutionError(DuplicateEntityListItemAttributeException.class, eea, ExecutionErrors.DuplicateEntityListItemAttribute.name(),
1519                        EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1520                        entityAttribute.getLastDetail().getEntityAttributeName());
1521            }
1522        }
1523        
1524        return entityListItemAttribute;
1525    }
1526
1527    public EntityMultipleListItemDefault createEntityMultipleListItemDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1528            final EntityListItem entityListItem, final boolean addMissingAttributes, final BasePK createdBy) {
1529        EntityMultipleListItemDefault entityListItemDefault = null;
1530
1531        checkEntityType(eea, entityAttribute, EntityAttributeTypes.MULTIPLELISTITEM);
1532
1533        if(eea == null || !eea.hasExecutionErrors()) {
1534            entityListItemDefault = coreControl.getEntityMultipleListItemDefault(entityAttribute, entityListItem);
1535
1536            if(entityListItemDefault == null) {
1537                coreControl.createEntityMultipleListItemDefault(entityAttribute, entityListItem, createdBy);
1538
1539                if(addMissingAttributes) {
1540                    new EntityInstancesMissingMultipleListItemEntityAttributeQuery().execute(entityAttribute, entityListItem).forEach(entityInstanceResult ->
1541                            coreControl.createEntityMultipleListItemAttribute(entityAttribute.getPrimaryKey(),
1542                                    entityInstanceResult.getEntityInstance(), entityListItem, createdBy));
1543                }
1544            } else {
1545                handleExecutionError(DuplicateEntityMultipleListItemDefaultException.class, eea, ExecutionErrors.DuplicateEntityMultipleListItemDefault.name(),
1546                        entityAttribute.getLastDetail().getEntityAttributeName(), entityListItem.getLastDetail().getEntityListItemName());
1547            }
1548        }
1549
1550        return entityListItemDefault;
1551    }
1552
1553    public void deleteEntityMultipleListItemDefault(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1554            final EntityListItem entityListItem, final BasePK deletedBy) {
1555        checkEntityType(eea, entityAttribute, EntityAttributeTypes.MULTIPLELISTITEM);
1556
1557        if(eea == null || !eea.hasExecutionErrors()) {
1558            var entityListItemDefault = coreControl.getEntityMultipleListItemDefaultForUpdate(entityAttribute, entityListItem);
1559
1560            if(entityListItemDefault == null) {
1561                handleExecutionError(UnknownEntityMultipleListItemDefaultException.class, eea, ExecutionErrors.UnknownEntityMultipleListItemDefault.name(),
1562                        entityAttribute.getLastDetail().getEntityAttributeName(), entityListItem.getLastDetail().getEntityListItemName());
1563            } else {
1564                coreControl.deleteEntityMultipleListItemDefault(entityListItemDefault, deletedBy);
1565            }
1566        }
1567    }
1568
1569    public EntityMultipleListItemAttribute createEntityMultipleListItemAttribute(final ExecutionErrorAccumulator eea, final EntityAttribute entityAttribute,
1570        final EntityInstance entityInstance, final EntityListItem entityListItem, final BasePK createdBy) {
1571        EntityMultipleListItemAttribute entityMultipleListItemAttribute = null;
1572        
1573        checkEntityType(eea, entityAttribute, entityInstance);
1574        
1575        if(eea == null || !eea.hasExecutionErrors()) {
1576            entityMultipleListItemAttribute = coreControl.getEntityMultipleListItemAttribute(entityAttribute, entityInstance, entityListItem);
1577
1578            if(entityMultipleListItemAttribute == null) {
1579                entityMultipleListItemAttribute = coreControl.createEntityMultipleListItemAttribute(entityAttribute, entityInstance, entityListItem, createdBy);
1580            } else {
1581                handleExecutionError(DuplicateEntityMultipleListItemAttributeException.class, eea, ExecutionErrors.DuplicateEntityMultipleListItemAttribute.name(),
1582                    EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityInstance),
1583                    entityAttribute.getLastDetail().getEntityAttributeName(),
1584                    entityListItem.getLastDetail().getEntityListItemName());
1585            }
1586        }
1587
1588        return entityMultipleListItemAttribute;
1589    }
1590    
1591}