001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.control.user.core.server.command; 018 019import com.echothree.control.user.core.common.edit.CoreEditFactory; 020import com.echothree.control.user.core.common.edit.EntityAttributeEdit; 021import com.echothree.control.user.core.common.form.EditEntityAttributeForm; 022import com.echothree.control.user.core.common.result.CoreResultFactory; 023import com.echothree.control.user.core.common.result.EditEntityAttributeResult; 024import com.echothree.control.user.core.common.spec.EntityAttributeUniversalSpec; 025import com.echothree.model.control.core.common.EntityAttributeTypes; 026import com.echothree.model.control.core.server.logic.EntityAttributeLogic; 027import com.echothree.model.control.party.common.PartyTypes; 028import com.echothree.model.control.security.common.SecurityRoleGroups; 029import com.echothree.model.control.security.common.SecurityRoles; 030import com.echothree.model.control.sequence.common.SequenceTypes; 031import com.echothree.model.control.sequence.server.control.SequenceControl; 032import com.echothree.model.control.sequence.server.logic.SequenceTypeLogic; 033import com.echothree.model.control.uom.server.logic.UnitOfMeasureTypeLogic; 034import com.echothree.model.data.core.server.entity.EntityAttribute; 035import com.echothree.model.data.sequence.server.entity.Sequence; 036import com.echothree.model.data.uom.server.entity.UnitOfMeasureType; 037import com.echothree.model.data.user.common.pk.UserVisitPK; 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.BaseAbstractEditCommand; 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; 049import javax.enterprise.context.RequestScoped; 050 051@RequestScoped 052public class EditEntityAttributeCommand 053 extends BaseAbstractEditCommand<EntityAttributeUniversalSpec, EntityAttributeEdit, EditEntityAttributeResult, EntityAttribute, EntityAttribute> { 054 055 private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION; 056 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 057 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 058 059 static { 060 COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of( 061 new PartyTypeDefinition(PartyTypes.UTILITY.name(), null), 062 new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of( 063 new SecurityRoleDefinition(SecurityRoleGroups.EntityAttribute.name(), SecurityRoles.Edit.name()) 064 )) 065 )); 066 067 SPEC_FIELD_DEFINITIONS = List.of( 068 new FieldDefinition("EntityRef", FieldType.ENTITY_REF, false, null, null), 069 new FieldDefinition("Uuid", FieldType.UUID, false, null, null), 070 new FieldDefinition("ComponentVendorName", FieldType.ENTITY_NAME, false, null, null), 071 new FieldDefinition("EntityTypeName", FieldType.ENTITY_TYPE_NAME, false, null, null), 072 new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, false, null, null) 073 ); 074 075 EDIT_FIELD_DEFINITIONS = List.of( 076 new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, true, null, null), 077 new FieldDefinition("TrackRevisions", FieldType.BOOLEAN, true, null, null), 078 new FieldDefinition("SortOrder", FieldType.SIGNED_INTEGER, true, null, null), 079 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L) 080 ); 081 } 082 083 /** Creates a new instance of EditEntityAttributeCommand */ 084 public EditEntityAttributeCommand() { 085 super(COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 086 } 087 088 @Override 089 protected ValidationResult validateEdit(Validator validator) { 090 var validationResult = validator.validate(edit, getEditFieldDefinitions()); 091 092 if(!validationResult.getHasErrors()) { 093 entityAttribute = EntityAttributeLogic.getInstance().getEntityAttributeByUniversalSpec(this, 094 spec); 095 096 if(!hasExecutionErrors()) { 097 var entityAttributeType = entityAttribute.getLastDetail().getEntityAttributeType(); 098 099 validationResult = CreateEntityAttributeCommand.AdditionalEntityAttributeValidation(edit, validator, entityAttributeType); 100 } 101 } 102 103 return validationResult; 104 } 105 106 @Override 107 public EditEntityAttributeResult getResult() { 108 return CoreResultFactory.getEditEntityAttributeResult(); 109 } 110 111 @Override 112 public EntityAttributeEdit getEdit() { 113 return CoreEditFactory.getEntityAttributeEdit(); 114 } 115 116 EntityAttribute entityAttribute = null; 117 118 @Override 119 public EntityAttribute getEntity(EditEntityAttributeResult result) { 120 entityAttribute = EntityAttributeLogic.getInstance().getEntityAttributeByUniversalSpec(this, 121 spec, editModeToEntityPermission(editMode)); 122 123 return entityAttribute; 124 } 125 126 @Override 127 public EntityAttribute getLockEntity(EntityAttribute entityAttribute) { 128 return entityAttribute; 129 } 130 131 @Override 132 public void fillInResult(EditEntityAttributeResult result, EntityAttribute entityAttribute) { 133 134 result.setEntityAttribute(coreControl.getEntityAttributeTransfer(getUserVisit(), entityAttribute, null)); 135 } 136 137 Sequence entityListItemSequence = null; 138 UnitOfMeasureType unitOfMeasureType = null; 139 140 @Override 141 public void doLock(EntityAttributeEdit edit, EntityAttribute entityAttribute) { 142 var entityAttributeDescription = coreControl.getEntityAttributeDescription(entityAttribute, getPreferredLanguage()); 143 var entityAttributeDetail = entityAttribute.getLastDetail(); 144 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 145 var entityAttributeType = EntityAttributeTypes.valueOf(entityAttributeTypeName); 146 147 edit.setEntityAttributeName(entityAttributeDetail.getEntityAttributeName()); 148 edit.setTrackRevisions(entityAttributeDetail.getTrackRevisions().toString()); 149 edit.setSortOrder(entityAttributeDetail.getSortOrder().toString()); 150 151 switch(entityAttributeType) { 152 case BLOB -> { 153 var entityAttributeBlob = coreControl.getEntityAttributeBlobForUpdate(entityAttribute); 154 155 edit.setCheckContentWebAddress(entityAttributeBlob.getCheckContentWebAddress().toString()); 156 } 157 case STRING -> { 158 var entityAttributeString = coreControl.getEntityAttributeStringForUpdate(entityAttribute); 159 160 if(entityAttributeString != null) { 161 edit.setValidationPattern(entityAttributeString.getValidationPattern()); 162 } 163 } 164 case INTEGER -> { 165 var entityAttributeInteger = coreControl.getEntityAttributeIntegerForUpdate(entityAttribute); 166 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 167 168 if(entityAttributeInteger != null) { 169 edit.setUpperLimitIntegerValue(entityAttributeInteger.getUpperLimitIntegerValue().toString()); 170 edit.setUpperRangeIntegerValue(entityAttributeInteger.getUpperRangeIntegerValue().toString()); 171 edit.setLowerRangeIntegerValue(entityAttributeInteger.getLowerRangeIntegerValue().toString()); 172 edit.setLowerLimitIntegerValue(entityAttributeInteger.getLowerLimitIntegerValue().toString()); 173 } 174 175 if(entityAttributeNumeric != null) { 176 unitOfMeasureType = entityAttributeNumeric.getUnitOfMeasureType(); 177 178 if(unitOfMeasureType != null) { 179 var unitOfMeasureTypeDetail = unitOfMeasureType.getLastDetail(); 180 181 edit.setUnitOfMeasureKindName(unitOfMeasureTypeDetail.getUnitOfMeasureKind().getLastDetail().getUnitOfMeasureKindName()); 182 edit.setUnitOfMeasureTypeName(unitOfMeasureTypeDetail.getUnitOfMeasureTypeName()); 183 } 184 } 185 } 186 case LONG -> { 187 var entityAttributeLong = coreControl.getEntityAttributeLongForUpdate(entityAttribute); 188 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 189 190 if(entityAttributeLong != null) { 191 edit.setUpperLimitLongValue(entityAttributeLong.getUpperLimitLongValue().toString()); 192 edit.setUpperRangeLongValue(entityAttributeLong.getUpperRangeLongValue().toString()); 193 edit.setLowerRangeLongValue(entityAttributeLong.getLowerRangeLongValue().toString()); 194 edit.setLowerLimitLongValue(entityAttributeLong.getLowerLimitLongValue().toString()); 195 } 196 197 if(entityAttributeNumeric != null) { 198 unitOfMeasureType = entityAttributeNumeric.getUnitOfMeasureType(); 199 200 if(unitOfMeasureType != null) { 201 var unitOfMeasureTypeDetail = unitOfMeasureType.getLastDetail(); 202 203 edit.setUnitOfMeasureKindName(unitOfMeasureTypeDetail.getUnitOfMeasureKind().getLastDetail().getUnitOfMeasureKindName()); 204 edit.setUnitOfMeasureTypeName(unitOfMeasureTypeDetail.getUnitOfMeasureTypeName()); 205 } 206 } 207 } 208 case LISTITEM, MULTIPLELISTITEM -> { 209 var entityAttributeListItem = coreControl.getEntityAttributeListItemForUpdate(entityAttribute); 210 211 if(entityAttributeListItem != null) { 212 entityListItemSequence = entityAttributeListItem.getEntityListItemSequence(); 213 214 edit.setEntityListItemSequenceName(entityListItemSequence == null ? null : entityListItemSequence.getLastDetail().getSequenceName()); 215 } 216 } 217 default -> { 218 } 219 } 220 221 if(entityAttributeDescription != null) { 222 edit.setDescription(entityAttributeDescription.getDescription()); 223 } 224 } 225 226 @Override 227 public void canUpdate(EntityAttribute entityAttribute) { 228 var entityAttributeName = edit.getEntityAttributeName(); 229 var duplicateEntityAttribute = coreControl.getEntityAttributeByName(entityAttribute.getLastDetail().getEntityType(), 230 entityAttributeName); 231 232 if(duplicateEntityAttribute == null || entityAttribute.equals(duplicateEntityAttribute)) { 233 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 234 var entityListItemSequenceName = entityAttributeTypeName.equals(EntityAttributeTypes.LISTITEM.name()) 235 || entityAttributeTypeName.equals(EntityAttributeTypes.MULTIPLELISTITEM.name()) ? 236 edit.getEntityListItemSequenceName() : null; 237 238 if(entityListItemSequenceName != null) { 239 var sequenceType = SequenceTypeLogic.getInstance().getSequenceTypeByName(this, SequenceTypes.ENTITY_LIST_ITEM.name()); 240 241 if(!hasExecutionErrors()) { 242 var sequenceControl = Session.getModelController(SequenceControl.class); 243 244 entityListItemSequence = sequenceControl.getSequenceByName(sequenceType, entityListItemSequenceName); 245 246 if(entityListItemSequence == null) { 247 addExecutionError(ExecutionErrors.UnknownEntityListItemSequenceName.name(), entityListItemSequenceName); 248 } 249 } 250 } 251 252 if(!hasExecutionErrors()) { 253 var unitOfMeasureKindName = edit.getUnitOfMeasureKindName(); 254 var unitOfMeasureTypeName = edit.getUnitOfMeasureTypeName(); 255 var parameterCount = (unitOfMeasureKindName == null ? 0 : 1) + (unitOfMeasureTypeName == null ? 0 : 1); 256 257 if(parameterCount == 0 || parameterCount == 2) { 258 if(parameterCount == 2) { 259 unitOfMeasureType = UnitOfMeasureTypeLogic.getInstance().getUnitOfMeasureTypeByName(this, unitOfMeasureKindName, unitOfMeasureTypeName); 260 } 261 } else { 262 addExecutionError(ExecutionErrors.InvalidParameterCount.name()); 263 } 264 } 265 } else { 266 addExecutionError(ExecutionErrors.DuplicateEntityAttributeName.name(), entityAttributeName); 267 } 268 } 269 270 @Override 271 public void doUpdate(EntityAttribute entityAttribute) { 272 var partyPK = getPartyPK(); 273 var entityAttributeDetailValue = coreControl.getEntityAttributeDetailValueForUpdate(entityAttribute); 274 var entityAttributeDescription = coreControl.getEntityAttributeDescriptionForUpdate(entityAttribute, getPreferredLanguage()); 275 var strCheckContentWebAddress = edit.getCheckContentWebAddress(); 276 var checkContentWebAddress = strCheckContentWebAddress == null ? null : Boolean.valueOf(strCheckContentWebAddress); 277 var validationPattern = edit.getValidationPattern(); 278 var strUpperRangeIntegerValue = edit.getUpperRangeIntegerValue(); 279 var upperRangeIntegerValue = strUpperRangeIntegerValue == null ? null : Integer.valueOf(strUpperRangeIntegerValue); 280 var strUpperLimitIntegerValue = edit.getUpperLimitIntegerValue(); 281 var upperLimitIntegerValue = strUpperLimitIntegerValue == null ? null : Integer.valueOf(strUpperLimitIntegerValue); 282 var strLowerLimitIntegerValue = edit.getLowerLimitIntegerValue(); 283 var lowerLimitIntegerValue = strLowerLimitIntegerValue == null ? null : Integer.valueOf(strLowerLimitIntegerValue); 284 var strLowerRangeIntegerValue = edit.getLowerRangeIntegerValue(); 285 var lowerRangeIntegerValue = strLowerRangeIntegerValue == null ? null : Integer.valueOf(strLowerRangeIntegerValue); 286 var strUpperRangeLongValue = edit.getUpperRangeLongValue(); 287 var upperRangeLongValue = strUpperRangeLongValue == null ? null : Long.valueOf(strUpperRangeLongValue); 288 var strUpperLimitLongValue = edit.getUpperLimitLongValue(); 289 var upperLimitLongValue = strUpperLimitLongValue == null ? null : Long.valueOf(strUpperLimitLongValue); 290 var strLowerLimitLongValue = edit.getLowerLimitLongValue(); 291 var lowerLimitLongValue = strLowerLimitLongValue == null ? null : Long.valueOf(strLowerLimitLongValue); 292 var strLowerRangeLongValue = edit.getLowerRangeLongValue(); 293 var lowerRangeLongValue = strLowerRangeLongValue == null ? null : Long.valueOf(strLowerRangeLongValue); 294 var description = edit.getDescription(); 295 296 entityAttributeDetailValue.setEntityAttributeName(edit.getEntityAttributeName()); 297 entityAttributeDetailValue.setTrackRevisions(Boolean.valueOf(edit.getTrackRevisions())); 298 entityAttributeDetailValue.setSortOrder(Integer.valueOf(edit.getSortOrder())); 299 300 EntityAttributeLogic.getInstance().updateEntityAttributeFromValue(session, entityAttributeDetailValue, partyPK); 301 302 var entityAttributeTypeName = entityAttribute.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 303 var entityAttributeType = EntityAttributeTypes.valueOf(entityAttributeTypeName); 304 305 switch(entityAttributeType) { 306 case BLOB -> { 307 var entityAttributeBlobValue = coreControl.getEntityAttributeBlobValueForUpdate(entityAttribute); 308 309 entityAttributeBlobValue.setCheckContentWebAddress(checkContentWebAddress); 310 coreControl.updateEntityAttributeBlobFromValue(entityAttributeBlobValue, partyPK); 311 } 312 case STRING -> { 313 var entityAttributeString = coreControl.getEntityAttributeStringForUpdate(entityAttribute); 314 315 if(entityAttributeString == null && validationPattern != null) { 316 coreControl.createEntityAttributeString(entityAttribute, validationPattern, partyPK); 317 } else if(entityAttributeString != null) { 318 if(validationPattern == null) { 319 coreControl.deleteEntityAttributeString(entityAttributeString, partyPK); 320 } else { 321 var entityAttributeStringValue = coreControl.getEntityAttributeStringValue(entityAttributeString); 322 323 entityAttributeStringValue.setValidationPattern(validationPattern); 324 coreControl.updateEntityAttributeStringFromValue(entityAttributeStringValue, partyPK); 325 } 326 } 327 } 328 case INTEGER -> { 329 var entityAttributeInteger = coreControl.getEntityAttributeIntegerForUpdate(entityAttribute); 330 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 331 332 if(entityAttributeInteger == null && (upperRangeIntegerValue != null || upperLimitIntegerValue != null || lowerLimitIntegerValue != null || lowerRangeIntegerValue != null)) { 333 coreControl.createEntityAttributeInteger(entityAttribute, upperRangeIntegerValue, upperLimitIntegerValue, lowerLimitIntegerValue, lowerRangeIntegerValue, partyPK); 334 } else if(entityAttributeInteger != null) { 335 if(upperRangeIntegerValue == null && upperLimitIntegerValue == null && lowerLimitIntegerValue == null && lowerRangeIntegerValue == null) { 336 coreControl.deleteEntityAttributeInteger(entityAttributeInteger, partyPK); 337 } else { 338 var entityAttributeIntegerValue = coreControl.getEntityAttributeIntegerValue(entityAttributeInteger); 339 340 entityAttributeIntegerValue.setUpperRangeIntegerValue(upperRangeIntegerValue); 341 entityAttributeIntegerValue.setUpperLimitIntegerValue(upperLimitIntegerValue); 342 entityAttributeIntegerValue.setLowerLimitIntegerValue(lowerLimitIntegerValue); 343 entityAttributeIntegerValue.setLowerRangeIntegerValue(lowerRangeIntegerValue); 344 coreControl.updateEntityAttributeIntegerFromValue(entityAttributeIntegerValue, partyPK); 345 } 346 } 347 348 if(entityAttributeNumeric == null && unitOfMeasureType != null) { 349 coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, partyPK); 350 } else if(entityAttributeNumeric != null) { 351 if(unitOfMeasureType == null) { 352 coreControl.deleteEntityAttributeNumeric(entityAttributeNumeric, partyPK); 353 } else { 354 var entityAttributeNumericValue = coreControl.getEntityAttributeNumericValue(entityAttributeNumeric); 355 356 entityAttributeNumericValue.setUnitOfMeasureTypePK(unitOfMeasureType.getPrimaryKey()); 357 coreControl.updateEntityAttributeNumericFromValue(entityAttributeNumericValue, partyPK); 358 } 359 } 360 } 361 case LONG -> { 362 var entityAttributeLong = coreControl.getEntityAttributeLongForUpdate(entityAttribute); 363 var entityAttributeNumeric = coreControl.getEntityAttributeNumericForUpdate(entityAttribute); 364 365 if(entityAttributeLong == null && (upperRangeLongValue != null || upperLimitLongValue != null || lowerLimitLongValue != null || lowerRangeLongValue != null)) { 366 coreControl.createEntityAttributeLong(entityAttribute, upperRangeLongValue, upperLimitLongValue, lowerLimitLongValue, lowerRangeLongValue, partyPK); 367 } else if(entityAttributeLong != null) { 368 if(upperRangeLongValue == null && upperLimitLongValue == null && lowerLimitLongValue == null && lowerRangeLongValue == null) { 369 coreControl.deleteEntityAttributeLong(entityAttributeLong, partyPK); 370 } else { 371 var entityAttributeLongValue = coreControl.getEntityAttributeLongValue(entityAttributeLong); 372 373 entityAttributeLongValue.setUpperRangeLongValue(upperRangeLongValue); 374 entityAttributeLongValue.setUpperLimitLongValue(upperLimitLongValue); 375 entityAttributeLongValue.setLowerLimitLongValue(lowerLimitLongValue); 376 entityAttributeLongValue.setLowerRangeLongValue(lowerRangeLongValue); 377 coreControl.updateEntityAttributeLongFromValue(entityAttributeLongValue, partyPK); 378 } 379 } 380 381 if(entityAttributeNumeric == null && unitOfMeasureType != null) { 382 coreControl.createEntityAttributeNumeric(entityAttribute, unitOfMeasureType, partyPK); 383 } else if(entityAttributeNumeric != null) { 384 if(unitOfMeasureType == null) { 385 coreControl.deleteEntityAttributeNumeric(entityAttributeNumeric, partyPK); 386 } else { 387 var entityAttributeNumericValue = coreControl.getEntityAttributeNumericValue(entityAttributeNumeric); 388 389 entityAttributeNumericValue.setUnitOfMeasureTypePK(unitOfMeasureType.getPrimaryKey()); 390 coreControl.updateEntityAttributeNumericFromValue(entityAttributeNumericValue, partyPK); 391 } 392 } 393 } 394 case LISTITEM, MULTIPLELISTITEM -> { 395 var entityAttributeListItem = coreControl.getEntityAttributeListItemForUpdate(entityAttribute); 396 397 if(entityAttributeListItem == null && entityListItemSequence != null) { 398 coreControl.createEntityAttributeListItem(entityAttribute, entityListItemSequence, partyPK); 399 } else if(entityAttributeListItem != null) { 400 if(entityListItemSequence == null) { 401 coreControl.deleteEntityAttributeListItem(entityAttributeListItem, partyPK); 402 } else { 403 var entityAttributeListItemValue = coreControl.getEntityAttributeListItemValue(entityAttributeListItem); 404 405 entityAttributeListItemValue.setEntityListItemSequencePK(entityListItemSequence.getPrimaryKey()); 406 coreControl.updateEntityAttributeListItemFromValue(entityAttributeListItemValue, partyPK); 407 } 408 } 409 } 410 default -> { 411 } 412 } 413 414 if(entityAttributeDescription == null && description != null) { 415 coreControl.createEntityAttributeDescription(entityAttribute, getPreferredLanguage(), description, partyPK); 416 } else if(entityAttributeDescription != null) { 417 if(description == null) { 418 coreControl.deleteEntityAttributeDescription(entityAttributeDescription, partyPK); 419 } else { 420 var entityAttributeDescriptionValue = coreControl.getEntityAttributeDescriptionValue(entityAttributeDescription); 421 422 entityAttributeDescriptionValue.setDescription(description); 423 coreControl.updateEntityAttributeDescriptionFromValue(entityAttributeDescriptionValue, partyPK); 424 } 425 } 426 } 427 428}