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}