001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 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.comment.server.command; 018 019import com.echothree.control.user.comment.common.edit.CommentEdit; 020import com.echothree.control.user.comment.common.edit.CommentEditFactory; 021import com.echothree.control.user.comment.common.form.EditCommentForm; 022import com.echothree.control.user.comment.common.result.CommentResultFactory; 023import com.echothree.control.user.comment.common.spec.CommentSpec; 024import com.echothree.model.control.comment.server.control.CommentControl; 025import com.echothree.model.control.core.common.EntityAttributeTypes; 026import com.echothree.model.control.core.server.control.MimeTypeControl; 027import com.echothree.model.control.party.server.control.PartyControl; 028import com.echothree.model.data.comment.server.entity.Comment; 029import com.echothree.model.data.core.server.entity.MimeType; 030import com.echothree.model.data.party.server.entity.Language; 031import com.echothree.model.data.user.common.pk.UserVisitPK; 032import com.echothree.util.common.command.BaseResult; 033import com.echothree.util.common.command.EditMode; 034import com.echothree.util.common.message.ExecutionErrors; 035import com.echothree.util.common.persistence.BasePK; 036import com.echothree.util.common.persistence.type.ByteArray; 037import com.echothree.util.common.validation.FieldDefinition; 038import com.echothree.util.common.validation.FieldType; 039import com.echothree.util.server.control.BaseEditCommand; 040import java.util.List; 041import javax.enterprise.context.Dependent; 042import javax.inject.Inject; 043 044@Dependent 045public class EditCommentCommand 046 extends BaseEditCommand<CommentSpec, CommentEdit> { 047 048 private final static List<FieldDefinition> SPEC_FIELD_DEFINITIONS; 049 private final static List<FieldDefinition> EDIT_FIELD_DEFINITIONS; 050 051 static { 052 SPEC_FIELD_DEFINITIONS = List.of( 053 new FieldDefinition("CommentName", FieldType.ENTITY_NAME, true, null, null) 054 ); 055 056 EDIT_FIELD_DEFINITIONS = List.of( 057 new FieldDefinition("LanguageIsoName", FieldType.ENTITY_NAME, true, null, null), 058 new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L), 059 new FieldDefinition("MimeTypeName", FieldType.MIME_TYPE, true, null, null), 060 new FieldDefinition("ClobComment", FieldType.STRING, false, 1L, null), 061 // BlobComment is not validated 062 new FieldDefinition("StringComment", FieldType.STRING, false, 1L, 512L) 063 ); 064 } 065 066 @Inject 067 CommentControl commentControl; 068 069 @Inject 070 MimeTypeControl mimeTypeControl; 071 072 @Inject 073 PartyControl partyControl; 074 075 076 /** Creates a new instance of EditCommentCommand */ 077 public EditCommentCommand() { 078 super(null, SPEC_FIELD_DEFINITIONS, EDIT_FIELD_DEFINITIONS); 079 } 080 081 protected void updateComment(CommentControl commentControl, Comment comment, Language language, String description, MimeType mimeType, BasePK updatedBy, ByteArray blob, String clob, 082 String string) { 083 if(lockEntityForUpdate(comment)) { 084 try { 085 var commentDetailValue = commentControl.getCommentDetailValueForUpdate(comment); 086 087 commentDetailValue.setLanguagePK(language.getPrimaryKey()); 088 commentDetailValue.setDescription(description); 089 commentDetailValue.setMimeTypePK(mimeType == null? null: mimeType.getPrimaryKey()); 090 commentControl.updateCommentFromValue(commentDetailValue, updatedBy); 091 092 var commentBlob = commentControl.getCommentBlobForUpdate(comment); 093 094 if(commentBlob != null) { 095 if(blob == null) { 096 commentControl.deleteCommentBlob(commentBlob, updatedBy); 097 } else { 098 var commentBlobValue = commentControl.getCommentBlobValue(commentBlob); 099 100 commentBlobValue.setBlob(blob); 101 commentControl.updateCommentBlobFromValue(commentBlobValue, updatedBy); 102 } 103 } else if(blob != null) { 104 commentControl.createCommentBlob(comment, blob, updatedBy); 105 } 106 107 var commentClob = commentControl.getCommentClobForUpdate(comment); 108 109 if(commentClob != null) { 110 if(clob == null) { 111 commentControl.deleteCommentClob(commentClob, updatedBy); 112 } else { 113 var commentClobValue = commentControl.getCommentClobValue(commentClob); 114 115 commentClobValue.setClob(clob); 116 commentControl.updateCommentClobFromValue(commentClobValue, updatedBy); 117 } 118 } else if(clob != null) { 119 commentControl.createCommentClob(comment, clob, updatedBy); 120 } 121 122 var commentString = commentControl.getCommentStringForUpdate(comment); 123 124 if(commentString != null) { 125 if(string == null) { 126 commentControl.deleteCommentString(commentString, updatedBy); 127 } else { 128 var commentStringValue = commentControl.getCommentStringValue(commentString); 129 130 commentStringValue.setString(string); 131 commentControl.updateCommentStringFromValue(commentStringValue, updatedBy); 132 } 133 } else if(string != null) { 134 commentControl.createCommentString(comment, string, updatedBy); 135 } 136 } finally { 137 unlockEntity(comment); 138 } 139 } else { 140 addExecutionError(ExecutionErrors.EntityLockStale.name()); 141 } 142 } 143 144 @Override 145 protected BaseResult execute() { 146 var result = CommentResultFactory.getEditCommentResult(); 147 var commentName = spec.getCommentName(); 148 var comment = commentControl.getCommentByName(commentName); 149 150 if(comment != null) { 151 if(editMode.equals(EditMode.LOCK)) { 152 if(lockEntity(comment)) { 153 var commentDetail = comment.getLastDetail(); 154 var edit = CommentEditFactory.getCommentEdit(); 155 var mimeType = commentDetail.getMimeType(); 156 157 result.setEdit(edit); 158 159 edit.setLanguageIsoName(commentDetail.getLanguage().getLanguageIsoName()); 160 edit.setDescription(commentDetail.getDescription()); 161 edit.setMimeTypeName(mimeType == null ? null : mimeType.getLastDetail().getMimeTypeName()); 162 163 if(mimeType == null) { 164 var commentString = commentControl.getCommentString(comment); 165 166 if(commentString != null) { 167 edit.setStringComment(commentString.getString()); 168 } 169 } else { 170 var entityAttributeTypeName = mimeType.getLastDetail().getEntityAttributeType().getEntityAttributeTypeName(); 171 172 // EntityAttributeTypes.BLOB.name() does not return anything in edit 173 if(entityAttributeTypeName.equals(EntityAttributeTypes.CLOB.name())) { 174 var commentClob = commentControl.getCommentClob(comment); 175 176 if(commentClob != null) { 177 edit.setClobComment(commentClob.getClob()); 178 } 179 } 180 } 181 } else { 182 addExecutionError(ExecutionErrors.EntityLockFailed.name()); 183 } 184 185 result.setComment(commentControl.getCommentTransfer(getUserVisit(), comment)); 186 result.setEntityLock(getEntityLockTransfer(comment)); 187 } else if(editMode.equals(EditMode.ABANDON)) { 188 unlockEntity(comment); 189 } else if(editMode.equals(EditMode.UPDATE)) { 190 var languageIsoName = edit.getLanguageIsoName(); 191 var language = partyControl.getLanguageByIsoName(languageIsoName); 192 193 if(language != null) { 194 BasePK updatedBy = getPartyPK(); 195 var description = edit.getDescription(); 196 var mimeTypeName = edit.getMimeTypeName(); 197 var mimeTypeUsageType = comment.getLastDetail().getCommentType().getLastDetail().getMimeTypeUsageType(); 198 199 if(mimeTypeName == null) { 200 if(mimeTypeUsageType == null) { 201 var string = edit.getStringComment(); 202 203 if(string != null) { 204 updateComment(commentControl, comment, language, description, null, updatedBy, null, null, string); 205 } else { 206 addExecutionError(ExecutionErrors.MissingCommentString.name()); 207 } 208 } else { 209 // No mimeTypeName was supplied, but yet we required a MimeTypeUsageType 210 addExecutionError(ExecutionErrors.InvalidMimeType.name()); 211 } 212 } else { 213 var mimeType = mimeTypeControl.getMimeTypeByName(mimeTypeName); 214 215 if(mimeType != null) { 216 if(mimeTypeUsageType != null) { 217 var mimeTypeUsage = mimeTypeControl.getMimeTypeUsage(mimeType, mimeTypeUsageType); 218 219 if(mimeTypeUsage != null) { 220 var entityAttributeType = mimeType.getLastDetail().getEntityAttributeType(); 221 var entityAttributeTypeName = entityAttributeType.getEntityAttributeTypeName(); 222 223 if(entityAttributeTypeName.equals(EntityAttributeTypes.BLOB.name())) { 224 var blob = edit.getBlobComment(); 225 226 if(blob != null) { 227 updateComment(commentControl, comment, language, description, mimeType, updatedBy, blob, null, null); 228 } else { 229 addExecutionError(ExecutionErrors.MissingCommentBlob.name()); 230 } 231 } else if(entityAttributeTypeName.equals(EntityAttributeTypes.CLOB.name())) { 232 var clob = edit.getClobComment(); 233 234 if(clob != null) { 235 updateComment(commentControl, comment, language, description, mimeType, updatedBy, null, clob, null); 236 } else { 237 addExecutionError(ExecutionErrors.MissingCommentClob.name()); 238 } 239 } else { 240 addExecutionError(ExecutionErrors.UnknownEntityAttributeTypeName.name(), 241 entityAttributeTypeName); 242 } 243 } else { 244 addExecutionError(ExecutionErrors.UnknownMimeTypeUsage.name()); 245 } 246 } else { 247 // mimeTypeName was supplied, and there shouldn't be one 248 addExecutionError(ExecutionErrors.InvalidMimeType.name()); 249 } 250 } else { 251 addExecutionError(ExecutionErrors.UnknownMimeTypeName.name(), mimeTypeName); 252 } 253 } 254 } else { 255 addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), languageIsoName); 256 } 257 258 if(hasExecutionErrors()) { 259 result.setComment(commentControl.getCommentTransfer(getUserVisit(), comment)); 260 result.setEntityLock(getEntityLockTransfer(comment)); 261 } 262 } 263 } else { 264 addExecutionError(ExecutionErrors.UnknownCommentName.name(), commentName); 265 } 266 267 return result; 268 } 269 270}