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.CoreEditFactory;
020import com.echothree.control.user.core.common.edit.EntityEntityAttributeEdit;
021import com.echothree.control.user.core.common.form.EditEntityEntityAttributeForm;
022import com.echothree.control.user.core.common.result.CoreResultFactory;
023import com.echothree.control.user.core.common.spec.EntityEntityAttributeSpec;
024import com.echothree.model.control.core.common.EntityAttributeTypes;
025import com.echothree.model.control.core.server.logic.EntityAttributeLogic;
026import com.echothree.model.control.core.server.logic.EntityInstanceLogic;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.data.core.server.entity.EntityEntityAttribute;
029import com.echothree.model.data.core.server.value.EntityEntityAttributeValue;
030import com.echothree.model.data.user.common.pk.UserVisitPK;
031import com.echothree.util.common.command.BaseResult;
032import com.echothree.util.common.command.EditMode;
033import com.echothree.util.common.message.ExecutionErrors;
034import com.echothree.util.common.validation.FieldDefinition;
035import com.echothree.util.common.validation.FieldType;
036import com.echothree.util.server.control.BaseEditCommand;
037import com.echothree.util.server.control.CommandSecurityDefinition;
038import com.echothree.util.server.control.PartyTypeDefinition;
039import com.echothree.util.server.persistence.PersistenceUtils;
040import java.util.Arrays;
041import java.util.Collections;
042import java.util.List;
043
044public class EditEntityEntityAttributeCommand
045        extends BaseEditCommand<EntityEntityAttributeSpec, EntityEntityAttributeEdit> {
046
047    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
048    private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS;
049    private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS;
050    
051    static {
052        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
053                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
054                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), null)
055        ));
056
057        SPEC_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
058                new FieldDefinition("EntityRef", FieldType.ENTITY_REF, false, null, null),
059                new FieldDefinition("Key", FieldType.KEY, false, null, null),
060                new FieldDefinition("Guid", FieldType.GUID, false, null, null),
061                new FieldDefinition("Ulid", FieldType.ULID, false, null, null),
062                new FieldDefinition("EntityAttributeName", FieldType.ENTITY_NAME, false, null, null),
063                new FieldDefinition("EntityAttributeUlid", FieldType.ULID, false, null, null)
064                ));
065        
066        EDIT_FIELD_DEFINITIONS = Collections.unmodifiableList(Arrays.asList(
067                new FieldDefinition("EntityRefAttribute", FieldType.ENTITY_REF, true, null, null)
068                ));
069    }
070    
071    /** Creates a new instance of EditEntityEntityAttributeCommand */
072    public EditEntityEntityAttributeCommand(UserVisitPK userVisitPK, EditEntityEntityAttributeForm form) {
073        super(userVisitPK, form, COMMAND_SECURITY_DEFINITION, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS);
074    }
075    
076    @Override
077    protected BaseResult execute() {
078        var coreControl = getCoreControl();
079        var result = CoreResultFactory.getEditEntityEntityAttributeResult();
080        var entityInstance = EntityInstanceLogic.getInstance().getEntityInstance(this, spec);
081
082        if(!hasExecutionErrors()) {
083            var entityAttribute = EntityAttributeLogic.getInstance().getEntityAttribute(this, entityInstance, spec, spec,
084                    EntityAttributeTypes.ENTITY);
085
086            if(!hasExecutionErrors()) {
087                EntityEntityAttribute entityEntityAttribute = null;
088                var basePK = PersistenceUtils.getInstance().getBasePKFromEntityInstance(entityInstance);
089
090                if(editMode.equals(EditMode.LOCK) || editMode.equals(EditMode.ABANDON)) {
091                    entityEntityAttribute = coreControl.getEntityEntityAttribute(entityAttribute, entityInstance);
092
093                    if(entityEntityAttribute != null) {
094                        if(editMode.equals(EditMode.LOCK)) {
095                            result.setEntityEntityAttribute(coreControl.getEntityEntityAttributeTransfer(getUserVisit(), entityEntityAttribute, entityInstance));
096
097                            if(lockEntity(basePK)) {
098                                EntityEntityAttributeEdit edit = CoreEditFactory.getEntityEntityAttributeEdit();
099
100                                result.setEdit(edit);
101                                edit.setEntityRefAttribute(EntityInstanceLogic.getInstance().getEntityRefFromEntityInstance(entityEntityAttribute.getEntityInstanceAttribute()));
102                            } else {
103                                addExecutionError(ExecutionErrors.EntityLockFailed.name());
104                            }
105                        } else { // EditMode.ABANDON
106                            unlockEntity(basePK);
107                            basePK = null;
108                        }
109                    } else {
110                        var entityTypeDetail = entityInstance.getEntityType().getLastDetail();
111
112                        addExecutionError(ExecutionErrors.UnknownEntityEntityAttribute.name(), basePK.getEntityRef(),
113                                entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
114                                entityTypeDetail.getEntityTypeName(), entityAttribute.getLastDetail().getEntityAttributeName());
115                    }
116                } else if(editMode.equals(EditMode.UPDATE)) {
117                    var entityRefAttribute = edit.getEntityRefAttribute();
118                    var entityInstanceAttribute = coreControl.getEntityInstanceByEntityRef(entityRefAttribute);
119
120                    if(entityInstanceAttribute != null) {
121                        entityEntityAttribute = coreControl.getEntityEntityAttributeForUpdate(entityAttribute, entityInstance);
122
123                        if(entityEntityAttribute != null) {
124                            if(lockEntityForUpdate(basePK)) {
125                                try {
126                                    EntityEntityAttributeValue entityEntityAttributeValue = coreControl.getEntityEntityAttributeValueForUpdate(entityEntityAttribute);
127
128                                    entityEntityAttributeValue.setEntityInstanceAttributePK(entityInstanceAttribute.getPrimaryKey());
129
130                                    coreControl.updateEntityEntityAttributeFromValue(entityEntityAttributeValue, getPartyPK());
131                                } finally {
132                                    unlockEntity(basePK);
133                                    basePK = null;
134                                }
135                            } else {
136                                addExecutionError(ExecutionErrors.EntityLockStale.name());
137                            }
138                        } else {
139                            var entityTypeDetail = entityInstance.getEntityType().getLastDetail();
140
141                            addExecutionError(ExecutionErrors.UnknownEntityEntityAttribute.name(), basePK.getEntityRef(),
142                                    entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(),
143                                    entityTypeDetail.getEntityTypeName(), entityAttribute.getLastDetail().getEntityAttributeName());
144                        }
145                    } else {
146                        addExecutionError(ExecutionErrors.UnknownEntityRefAttribute.name(), entityRefAttribute);
147                    }
148                }
149
150                if(basePK != null) {
151                    result.setEntityLock(getEntityLockTransfer(basePK));
152                }
153
154                if(entityEntityAttribute != null) {
155                    result.setEntityEntityAttribute(coreControl.getEntityEntityAttributeTransfer(getUserVisit(), entityEntityAttribute, entityInstance));
156                }
157            }
158        }
159
160        return result;
161    }
162    
163}