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.util.server.control;
018
019import com.echothree.model.control.core.common.transfer.EntityLockTransfer;
020import com.echothree.model.control.core.server.control.EntityLockControl;
021import com.echothree.model.data.user.common.pk.UserVisitPK;
022import com.echothree.util.common.command.CommandResult;
023import com.echothree.util.common.exception.EntityLockException;
024import com.echothree.util.common.validation.FieldDefinition;
025import com.echothree.util.common.command.EditMode;
026import com.echothree.util.common.form.BaseEdit;
027import com.echothree.util.common.form.BaseEditForm;
028import com.echothree.util.common.form.BaseForm;
029import com.echothree.util.common.form.BaseSpec;
030import com.echothree.util.common.form.ValidationResult;
031import com.echothree.util.common.persistence.BasePK;
032import com.echothree.util.server.persistence.BaseEntity;
033import com.echothree.util.server.persistence.BaseValue;
034import com.echothree.util.server.persistence.Session;
035import com.echothree.util.server.validation.Validator;
036import java.util.List;
037import java.util.concurrent.Future;
038
039public abstract class BaseEditCommand<S extends BaseSpec, E extends BaseEdit>
040        extends BaseCommand {
041    
042    private EntityLockControl entityLockControl = null;
043    private List<FieldDefinition> specFieldDefinitions;
044    private List<FieldDefinition> editFieldDefinitions;
045    protected EditMode editMode = null;
046    protected S spec = null;
047    protected E edit = null;
048    
049    protected BaseEditCommand(CommandSecurityDefinition commandSecurityDefinition,
050            List<FieldDefinition> specFieldDefinitions, List<FieldDefinition> editFieldDefinitions) {
051        super(commandSecurityDefinition);
052        
053        this.specFieldDefinitions = specFieldDefinitions;
054        this.editFieldDefinitions = editFieldDefinitions;
055    }
056
057    private void  initForRun(BaseEditForm<S, E> editForm) {
058        if(editForm != null) {
059            editMode = editForm.getEditMode();
060            spec = editForm.getSpec();
061            edit = editForm.getEdit();
062        }
063    }
064
065    public Future<CommandResult> runAsync(UserVisitPK userVisitPK, BaseEditForm<S, E> editForm) {
066        initForRun(editForm);
067
068        return super.runAsync(userVisitPK);
069    }
070
071    public CommandResult run(UserVisitPK userVisitPK, BaseEditForm<S, E> editForm) {
072        initForRun(editForm);
073
074        return super.run(userVisitPK);
075    }
076
077    protected void setupValidatorForSpec(Validator validator) {
078        // Nothing.
079    }
080    
081    protected void setupValidatorForEdit(Validator validator, BaseForm specForm) {
082        // Nothing.
083    }
084    
085    protected ValidationResult validateSpec(Validator validator) {
086        return validator.validate(spec, getSpecFieldDefinitions());
087    }
088    
089    protected ValidationResult validateEdit(Validator validator) {
090        return validator.validate(edit, getEditFieldDefinitions());
091    }
092    
093    protected ValidationResult validateLock() {
094        var validator = new Validator(this);
095        
096        setupValidatorForSpec(validator);
097        
098        return validateSpec(validator);
099    }
100    
101    protected void saveResultAfterEditValidatorErrors() {
102        // Nothing.
103    }
104    
105    protected ValidationResult validateUpdate() {
106        var validator = new Validator(this);
107        ValidationResult validationResult;
108        BaseForm specForm = spec;
109        
110        setupValidatorForSpec(validator);
111        validationResult = validateSpec(validator);
112        
113        if(!validationResult.getHasErrors()) {
114            setupValidatorForEdit(validator, specForm);
115            validationResult = validateEdit(validator);
116            
117            if(validationResult.getHasErrors()) {
118                saveResultAfterEditValidatorErrors();
119            }
120        }
121        
122        return validationResult;
123    }
124    
125    @Override
126    protected ValidationResult validate() {
127        ValidationResult validationResult = null;
128        
129        if(editMode.equals(EditMode.LOCK)) {
130            validationResult = validateLock();
131        } else if(editMode.equals(EditMode.UPDATE)) {
132            validationResult = validateUpdate();
133        }
134        
135        return validationResult;
136    }
137    
138    protected List<FieldDefinition> getSpecFieldDefinitions() {
139        return specFieldDefinitions;
140    }
141    
142    protected void setSpecFieldDefinitions(List<FieldDefinition> specFieldDefinitions) {
143        this.specFieldDefinitions = specFieldDefinitions;
144    }
145    
146    protected List<FieldDefinition> getEditFieldDefinitions() {
147        return editFieldDefinitions;
148    }
149    
150    protected void setEditFieldDefinitions(List<FieldDefinition> editFieldDefinitions) {
151        this.editFieldDefinitions = editFieldDefinitions;
152    }
153    
154    public EntityLockControl getEntityLockControl() {
155        if(entityLockControl == null) {
156            entityLockControl = Session.getModelController(EntityLockControl.class);
157        }
158        
159        return entityLockControl;
160    }
161    
162    public EntityLockTransfer getEntityLockTransfer(BaseEntity lockTarget)
163            throws EntityLockException {
164        return getEntityLockControl().getEntityLockTransfer(getUserVisit(), lockTarget);
165    }
166
167    public EntityLockTransfer getEntityLockTransfer(BasePK lockTarget)
168            throws EntityLockException {
169        return getEntityLockControl().getEntityLockTransfer(getUserVisit(), lockTarget);
170    }
171
172    public EntityLockTransfer getEntityLockTransfer(BaseValue lockTarget)
173            throws EntityLockException {
174        return getEntityLockControl().getEntityLockTransfer(getUserVisit(), lockTarget);
175    }
176
177    public boolean lockEntity(BaseEntity lockTarget)
178            throws EntityLockException {
179        return getEntityLockControl().lockEntity(lockTarget, getPartyPK()) != 0;
180    }
181
182    public boolean lockEntity(BasePK lockTarget)
183            throws EntityLockException {
184        return getEntityLockControl().lockEntity(lockTarget, getPartyPK()) != 0;
185    }
186
187    public boolean lockEntity(BaseValue lockTarget)
188            throws EntityLockException {
189        return getEntityLockControl().lockEntity(lockTarget, getPartyPK()) != 0;
190    }
191
192    public boolean lockEntityForUpdate(BaseEntity lockTarget)
193            throws EntityLockException {
194        return getEntityLockControl().lockEntityForUpdate(lockTarget, getPartyPK());
195    }
196
197    public boolean lockEntityForUpdate(BasePK lockTarget)
198            throws EntityLockException {
199        return getEntityLockControl().lockEntityForUpdate(lockTarget, getPartyPK());
200    }
201
202    public boolean lockEntityForUpdate(BaseValue lockTarget)
203            throws EntityLockException {
204        return getEntityLockControl().lockEntityForUpdate(lockTarget, getPartyPK());
205    }
206
207    public boolean unlockEntity(BaseEntity lockTarget)
208            throws EntityLockException {
209        return getEntityLockControl().unlockEntity(lockTarget, getPartyPK());
210    }
211
212    public boolean unlockEntity(BasePK lockTarget)
213            throws EntityLockException {
214        return getEntityLockControl().unlockEntity(lockTarget, getPartyPK());
215    }
216
217    public boolean unlockEntity(BaseValue lockTarget)
218            throws EntityLockException {
219        return getEntityLockControl().unlockEntity(lockTarget, getPartyPK());
220    }
221
222    public boolean isEntityLocked(BaseEntity lockTarget)
223            throws EntityLockException {
224        return getEntityLockControl().isEntityLocked(lockTarget, getPartyPK());
225    }
226
227    public boolean isEntityLocked(BasePK lockTarget)
228            throws EntityLockException {
229        return getEntityLockControl().isEntityLocked(lockTarget, getPartyPK());
230    }
231
232    public boolean isEntityLocked(BaseValue lockTarget)
233            throws EntityLockException {
234        return getEntityLockControl().isEntityLocked(lockTarget, getPartyPK());
235    }
236    
237}