001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 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.control.user.core.server.command;
018
019import com.echothree.control.user.core.common.edit.EntityAttributeEdit;
020import com.echothree.control.user.core.common.form.CreateEntityAttributeForm;
021import com.echothree.control.user.core.common.result.CoreResultFactory;
022import com.echothree.model.control.core.common.EntityAttributeTypes;
023import com.echothree.model.control.core.server.logic.EntityAttributeLogic;
024import com.echothree.model.control.core.server.logic.EntityTypeLogic;
025import com.echothree.model.control.party.common.PartyTypes;
026import com.echothree.model.control.security.common.SecurityRoleGroups;
027import com.echothree.model.control.security.common.SecurityRoles;
028import com.echothree.model.control.sequence.common.SequenceTypes;
029import com.echothree.model.control.sequence.server.control.SequenceControl;
030import com.echothree.model.control.sequence.server.logic.SequenceTypeLogic;
031import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic;
032import com.echothree.model.data.core.server.entity.EntityAttribute;
033import com.echothree.model.data.core.server.entity.EntityAttributeType;
034import com.echothree.model.data.sequence.server.entity.Sequence;
035import com.echothree.model.data.uom.server.entity.UnitOfMeasureType;
036import com.echothree.model.data.user.common.pk.UserVisitPK;
037import com.echothree.util.common.command.BaseResult;
038import com.echothree.util.common.form.ValidationResult;
039import com.echothree.util.common.message.ExecutionErrors;
040import com.echothree.util.common.validation.FieldDefinition;
041import com.echothree.util.common.validation.FieldType;
042import com.echothree.util.server.control.BaseSimpleCommand;
043import com.echothree.util.server.control.CommandSecurityDefinition;
044import com.echothree.util.server.control.PartyTypeDefinition;
045import com.echothree.util.server.control.SecurityRoleDefinition;
046import com.echothree.util.server.persistence.Session;
047import com.echothree.util.server.validation.Validator;
048import java.util.List;
049
050public class CreateEntityAttributeCommand
051        extends BaseSimpleCommand<CreateEntityAttributeForm> {
052    
053    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
054    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
055    
056    private final static List<FieldDefinition> BLOB_FORM_FIELD_DEFINITIONS;
057    private final static List<FieldDefinition> STRING_FORM_FIELD_DEFINITIONS;
058    private final static List<FieldDefinition> INTEGER_FORM_FIELD_DEFINITIONS;
059    private final static List<FieldDefinition> LONG_FORM_FIELD_DEFINITIONS;
060    private final static List<FieldDefinition> LISTITEM_FORM_FIELD_DEFINITIONS;
061    private final static List<FieldDefinition> MULTIPLELISTITEM_FORM_FIELD_DEFINITIONS;
062    private final static List<FieldDefinition> OTHER_FORM_FIELD_DEFINITIONS;
063    
064    static {
065        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
066                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
067                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
068                        new SecurityRoleDefinition(SecurityRoleGroups.EntityAttribute.name(), SecurityRoles.Create.name())
069                ))
070        ));
071        
072        FORM_FIELD_DEFINITIONS = List.of(
073                new FieldDefinition("EntityRef", FieldType.ENTITY_REF, false, null, null),
074                new FieldDefinition("Key", FieldType.KEY, false, null, null),
075                new FieldDefinition("Guid", FieldType.GUID, false, null, null),
076                new FieldDefinition("Ulid", FieldType.ULID, false, null, null),
077                new FieldDefinition("ComponentVendorName", FieldType.ENTITY_NAME, false, null, null),
078                new FieldDefinition("EntityTypeName", FieldType.ENTITY_TYPE_NAME, false, null, null),
079                new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, false, null, null),
080                new FieldDefinition("EntityAttributeTypeName", FieldType.ENTITY_NAME, true, null, null),
081                new FieldDefinition("TrackRevisions", FieldType.BOOLEAN, true, null, null),
082                new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null),
083                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L)
084        );
085        
086        BLOB_FORM_FIELD_DEFINITIONS = List.of(
087                new FieldDefinition("CheckContentWebAddress", FieldType.BOOLEAN, true, null, null),
088                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
089                new FieldDefinition("UpperRangeIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
090                new FieldDefinition("UpperLimitIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
091                new FieldDefinition("LowerLimitIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
092                new FieldDefinition("LowerRangeIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
093                new FieldDefinition("UpperRangeLongValue", FieldType.SIGNED_LONG, false, null, null),
094                new FieldDefinition("UpperLimitLongValue", FieldType.SIGNED_LONG, false, null, null),
095                new FieldDefinition("LowerLimitLongValue", FieldType.SIGNED_LONG, false, null, null),
096                new FieldDefinition("LowerRangeLongValue", FieldType.SIGNED_LONG, false, null, null),
097                new FieldDefinition("UnitOfMeasureKindName", FieldType.ENTITY_NAME, false, null, null),
098                new FieldDefinition("UnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
099                new FieldDefinition("EntityListItemSequenceName", FieldType.ENTITY_NAME, false, null, null)
100        );
101        
102        STRING_FORM_FIELD_DEFINITIONS = List.of(
103                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
104                new FieldDefinition("ValidationPattern", FieldType.REGULAR_EXPRESSION, false, null, null),
105                new FieldDefinition("UpperRangeIntegerValue", FieldType.NULL, false, null, null),
106                new FieldDefinition("UpperLimitIntegerValue", FieldType.NULL, false, null, null),
107                new FieldDefinition("LowerLimitIntegerValue", FieldType.NULL, false, null, null),
108                new FieldDefinition("LowerRangeIntegerValue", FieldType.NULL, false, null, null),
109                new FieldDefinition("UpperRangeLongValue", FieldType.NULL, false, null, null),
110                new FieldDefinition("UpperLimitLongValue", FieldType.NULL, false, null, null),
111                new FieldDefinition("LowerLimitLongValue", FieldType.NULL, false, null, null),
112                new FieldDefinition("LowerRangeLongValue", FieldType.NULL, false, null, null),
113                new FieldDefinition("UnitOfMeasureKindName", FieldType.NULL, false, null, null),
114                new FieldDefinition("UnitOfMeasureTypeName", FieldType.NULL, false, null, null),
115                new FieldDefinition("EntityListItemSequenceName", FieldType.NULL, false, null, null)
116        );
117        
118        INTEGER_FORM_FIELD_DEFINITIONS = List.of(
119                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
120                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
121                new FieldDefinition("UpperRangeIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
122                new FieldDefinition("UpperLimitIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
123                new FieldDefinition("LowerLimitIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
124                new FieldDefinition("LowerRangeIntegerValue", FieldType.SIGNED_INTEGER, false, null, null),
125                new FieldDefinition("UpperRangeLongValue", FieldType.NULL, false, null, null),
126                new FieldDefinition("UpperLimitLongValue", FieldType.NULL, false, null, null),
127                new FieldDefinition("LowerLimitLongValue", FieldType.NULL, false, null, null),
128                new FieldDefinition("LowerRangeLongValue", FieldType.NULL, false, null, null),
129                new FieldDefinition("UnitOfMeasureKindName", FieldType.ENTITY_NAME, false, null, null),
130                new FieldDefinition("UnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
131                new FieldDefinition("EntityListItemSequenceName", FieldType.NULL, false, null, null)
132        );
133        
134        LONG_FORM_FIELD_DEFINITIONS = List.of(
135                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
136                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
137                new FieldDefinition("UpperRangeIntegerValue", FieldType.NULL, false, null, null),
138                new FieldDefinition("UpperLimitIntegerValue", FieldType.NULL, false, null, null),
139                new FieldDefinition("LowerLimitIntegerValue", FieldType.NULL, false, null, null),
140                new FieldDefinition("LowerRangeIntegerValue", FieldType.NULL, false, null, null),
141                new FieldDefinition("UpperRangeLongValue", FieldType.SIGNED_LONG, false, null, null),
142                new FieldDefinition("UpperLimitLongValue", FieldType.SIGNED_LONG, false, null, null),
143                new FieldDefinition("LowerLimitLongValue", FieldType.SIGNED_LONG, false, null, null),
144                new FieldDefinition("LowerRangeLongValue", FieldType.SIGNED_LONG, false, null, null),
145                new FieldDefinition("UnitOfMeasureKindName", FieldType.ENTITY_NAME, false, null, null),
146                new FieldDefinition("UnitOfMeasureTypeName", FieldType.ENTITY_NAME, false, null, null),
147                new FieldDefinition("EntityListItemSequenceName", FieldType.NULL, false, null, null)
148        );
149        
150        LISTITEM_FORM_FIELD_DEFINITIONS = List.of(
151                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
152                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
153                new FieldDefinition("UpperRangeIntegerValue", FieldType.NULL, false, null, null),
154                new FieldDefinition("UpperLimitIntegerValue", FieldType.NULL, false, null, null),
155                new FieldDefinition("LowerLimitIntegerValue", FieldType.NULL, false, null, null),
156                new FieldDefinition("LowerRangeIntegerValue", FieldType.NULL, false, null, null),
157                new FieldDefinition("UpperRangeLongValue", FieldType.NULL, false, null, null),
158                new FieldDefinition("UpperLimitLongValue", FieldType.NULL, false, null, null),
159                new FieldDefinition("LowerLimitLongValue", FieldType.NULL, false, null, null),
160                new FieldDefinition("LowerRangeLongValue", FieldType.NULL, false, null, null),
161                new FieldDefinition("UnitOfMeasureKindName", FieldType.NULL, false, null, null),
162                new FieldDefinition("UnitOfMeasureTypeName", FieldType.NULL, false, null, null),
163                new FieldDefinition("EntityListItemSequenceName", FieldType.ENTITY_NAME, false, null, null)
164        );
165        
166        MULTIPLELISTITEM_FORM_FIELD_DEFINITIONS = List.of(
167                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
168                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
169                new FieldDefinition("UpperRangeIntegerValue", FieldType.NULL, false, null, null),
170                new FieldDefinition("UpperLimitIntegerValue", FieldType.NULL, false, null, null),
171                new FieldDefinition("LowerLimitIntegerValue", FieldType.NULL, false, null, null),
172                new FieldDefinition("LowerRangeIntegerValue", FieldType.NULL, false, null, null),
173                new FieldDefinition("UpperRangeLongValue", FieldType.NULL, false, null, null),
174                new FieldDefinition("UpperLimitLongValue", FieldType.NULL, false, null, null),
175                new FieldDefinition("LowerLimitLongValue", FieldType.NULL, false, null, null),
176                new FieldDefinition("LowerRangeLongValue", FieldType.NULL, false, null, null),
177                new FieldDefinition("UnitOfMeasureKindName", FieldType.NULL, false, null, null),
178                new FieldDefinition("UnitOfMeasureTypeName", FieldType.NULL, false, null, null),
179                new FieldDefinition("EntityListItemSequenceName", FieldType.ENTITY_NAME, false, null, null)
180        );
181        
182        OTHER_FORM_FIELD_DEFINITIONS = List.of(
183                new FieldDefinition("CheckContentWebAddress", FieldType.NULL, false, null, null),
184                new FieldDefinition("ValidationPattern", FieldType.NULL, false, null, null),
185                new FieldDefinition("UpperRangeIntegerValue", FieldType.NULL, false, null, null),
186                new FieldDefinition("UpperLimitIntegerValue", FieldType.NULL, false, null, null),
187                new FieldDefinition("LowerLimitIntegerValue", FieldType.NULL, false, null, null),
188                new FieldDefinition("LowerRangeIntegerValue", FieldType.NULL, false, null, null),
189                new FieldDefinition("UpperRangeLongValue", FieldType.NULL, false, null, null),
190                new FieldDefinition("UpperLimitLongValue", FieldType.NULL, false, null, null),
191                new FieldDefinition("LowerLimitLongValue", FieldType.NULL, false, null, null),
192                new FieldDefinition("LowerRangeLongValue", FieldType.NULL, false, null, null),
193                new FieldDefinition("UnitOfMeasureKindName", FieldType.NULL, false, null, null),
194                new FieldDefinition("UnitOfMeasureTypeName", FieldType.NULL, false, null, null),
195                new FieldDefinition("EntityListItemSequenceName", FieldType.NULL, false, null, null)
196        );
197    }
198    
199    /** Creates a new instance of CreateEntityAttributeCommand */
200    public CreateEntityAttributeCommand(UserVisitPK userVisitPK, CreateEntityAttributeForm form) {
201        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
202    }
203    
204    public static ValidationResult AdditionalEntityAttributeValidation(EntityAttributeEdit edit, Validator validator,
205            EntityAttributeType entityAttributeType) {
206        return switch(EntityAttributeTypes.valueOf(entityAttributeType.getEntityAttributeTypeName())) {
207            case BLOB -> validator.validate(edit, BLOB_FORM_FIELD_DEFINITIONS);
208            case STRING -> validator.validate(edit, STRING_FORM_FIELD_DEFINITIONS);
209            case INTEGER -> validator.validate(edit, INTEGER_FORM_FIELD_DEFINITIONS);
210            case LONG -> validator.validate(edit, LONG_FORM_FIELD_DEFINITIONS);
211            case LISTITEM -> validator.validate(edit, LISTITEM_FORM_FIELD_DEFINITIONS);
212            case MULTIPLELISTITEM -> validator.validate(edit, MULTIPLELISTITEM_FORM_FIELD_DEFINITIONS);
213            default -> validator.validate(edit, OTHER_FORM_FIELD_DEFINITIONS);
214        };
215    }
216    
217    @Override
218    protected ValidationResult validate() {
219        var validator = new Validator(this);
220        var validationResult = validator.validate(form, FORM_FIELD_DEFINITIONS);
221        
222        if(!validationResult.getHasErrors()) {
223            var entityAttributeType = EntityAttributeLogic.getInstance().getEntityAttributeTypeByName(this, form.getEntityAttributeTypeName());
224            
225            if(!hasExecutionErrors()) {
226                validationResult = AdditionalEntityAttributeValidation(form, validator, entityAttributeType);
227            }
228        }
229        
230        return validationResult;
231    }
232    
233    @Override
234    protected BaseResult execute() {
235        var result = CoreResultFactory.getCreateEntityAttributeResult();
236        EntityAttribute entityAttribute = null;
237        
238        if(!hasExecutionErrors()) {
239            var unitOfMeasureKindName = form.getUnitOfMeasureKindName();
240            var unitOfMeasureTypeName = form.getUnitOfMeasureTypeName();
241            var parameterCount = (unitOfMeasureKindName == null ? 0 : 1) + (unitOfMeasureTypeName == null ? 0 : 1);
242
243            if(parameterCount == 0 || parameterCount == 2) {
244                var entityType = EntityTypeLogic.getInstance().getEntityTypeByUniversalSpec(this, form);
245                var entityAttributeTypeName = form.getEntityAttributeTypeName();
246                var entityAttributeType = EntityAttributeLogic.getInstance().getEntityAttributeTypeByName(this, entityAttributeTypeName);
247
248                if(!hasExecutionErrors()) {
249                    var entityListItemSequenceName = entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name())
250                            || entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name()) ?
251                            form.getEntityListItemSequenceName() : null;
252                    Sequence entityListItemSequence = null;
253
254                    if(entityListItemSequenceName != null) {
255                        var sequenceType = SequenceTypeLogic.getInstance().getSequenceTypeByName(this, SequenceTypes.ENTITY_LIST_ITEM.name());
256
257                        if(!hasExecutionErrors()) {
258                            var sequenceControl = Session.getModelController(SequenceControl.class);
259
260                            entityListItemSequence = sequenceControl.getSequenceByName(sequenceType, entityListItemSequenceName);
261
262                            if(entityListItemSequence == null) {
263                                addExecutionError(ExecutionErrors.UnknownEntityListItemSequenceName.name(), entityListItemSequenceName);
264                            }
265                        }
266                    }
267
268                    if(!hasExecutionErrors()) {
269                        UnitOfMeasureType unitOfMeasureType = null;
270
271                        if(parameterCount == 2) {
272                            unitOfMeasureType = UnitOfMeasureTypeLogic.getInstance().getUnitOfMeasureTypeByName(this, unitOfMeasureKindName, unitOfMeasureTypeName);
273                        }
274
275                        if(!hasExecutionErrors()) {
276                            var partyPK = getPartyPK();
277                            var entityAttributeName = form.getEntityAttributeName();
278                            var trackRevisions = Boolean.valueOf(form.getTrackRevisions());
279                            var strCheckContentWebAddress = form.getCheckContentWebAddress();
280                            var checkContentWebAddress = strCheckContentWebAddress == null ? null : Boolean.valueOf(strCheckContentWebAddress);
281                            var validationPattern = form.getValidationPattern();
282                            var strUpperRangeIntegerValue = form.getUpperRangeIntegerValue();
283                            var upperRangeIntegerValue = strUpperRangeIntegerValue == null ? null : Integer.valueOf(strUpperRangeIntegerValue);
284                            var strUpperLimitIntegerValue = form.getUpperLimitIntegerValue();
285                            var upperLimitIntegerValue = strUpperLimitIntegerValue == null ? null : Integer.valueOf(strUpperLimitIntegerValue);
286                            var strLowerLimitIntegerValue = form.getLowerLimitIntegerValue();
287                            var lowerLimitIntegerValue = strLowerLimitIntegerValue == null ? null : Integer.valueOf(strLowerLimitIntegerValue);
288                            var strLowerRangeIntegerValue = form.getLowerRangeIntegerValue();
289                            var lowerRangeIntegerValue = strLowerRangeIntegerValue == null ? null : Integer.valueOf(strLowerRangeIntegerValue);
290                            var strUpperRangeLongValue = form.getUpperRangeLongValue();
291                            var upperRangeLongValue = strUpperRangeLongValue == null ? null : Long.valueOf(strUpperRangeLongValue);
292                            var strUpperLimitLongValue = form.getUpperLimitLongValue();
293                            var upperLimitLongValue = strUpperLimitLongValue == null ? null : Long.valueOf(strUpperLimitLongValue);
294                            var strLowerLimitLongValue = form.getLowerLimitLongValue();
295                            var lowerLimitLongValue = strLowerLimitLongValue == null ? null : Long.valueOf(strLowerLimitLongValue);
296                            var strLowerRangeLongValue = form.getLowerRangeLongValue();
297                            var lowerRangeLongValue = strLowerRangeLongValue == null ? null : Long.valueOf(strLowerRangeLongValue);
298                            var sortOrder = Integer.valueOf(form.getSortOrder());
299                            var description = form.getDescription();
300
301                            entityAttribute = EntityAttributeLogic.getInstance().createEntityAttribute(this, entityType,
302                                    entityAttributeName, entityAttributeType, trackRevisions, checkContentWebAddress,
303                                    validationPattern, upperRangeIntegerValue, upperLimitIntegerValue, lowerLimitIntegerValue,
304                                    lowerRangeIntegerValue, upperRangeLongValue, upperLimitLongValue, lowerLimitLongValue,
305                                    lowerRangeLongValue, entityListItemSequence, unitOfMeasureType, sortOrder, partyPK,
306                                    getPreferredLanguage(), description);
307                        }
308                    }
309                }
310            } else {
311                addExecutionError(ExecutionErrors.InvalidParameterCount.name());
312            }
313        }
314        
315        if(entityAttribute != null) {
316            var basePK = entityAttribute.getPrimaryKey();
317
318            result.setEntityAttributeName(entityAttribute.getLastDetail().getEntityAttributeName());
319            result.setEntityRef(basePK.getEntityRef());
320        }
321        
322        return result;
323    }
324
325}