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