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.form.CreateCommentForm;
020import com.echothree.control.user.comment.common.result.CommentResultFactory;
021import com.echothree.model.control.comment.server.control.CommentControl;
022import com.echothree.model.control.core.common.EntityAttributeTypes;
023import com.echothree.model.control.core.server.control.EntityInstanceControl;
024import com.echothree.model.control.core.server.control.MimeTypeControl;
025import com.echothree.model.control.party.server.control.PartyControl;
026import com.echothree.model.control.sequence.common.SequenceTypes;
027import com.echothree.model.control.sequence.server.control.SequenceControl;
028import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic;
029import com.echothree.model.control.workflow.server.control.WorkflowControl;
030import com.echothree.model.data.comment.server.entity.CommentType;
031import com.echothree.model.data.core.server.entity.EntityInstance;
032import com.echothree.model.data.core.server.entity.MimeType;
033import com.echothree.model.data.party.server.entity.Language;
034import com.echothree.model.data.user.common.pk.UserVisitPK;
035import com.echothree.util.common.command.BaseResult;
036import com.echothree.util.common.message.ExecutionErrors;
037import com.echothree.util.common.persistence.BasePK;
038import com.echothree.util.common.persistence.type.ByteArray;
039import com.echothree.util.common.validation.FieldDefinition;
040import com.echothree.util.common.validation.FieldType;
041import com.echothree.util.server.control.BaseSimpleCommand;
042import com.echothree.util.server.persistence.Session;
043import java.util.List;
044import javax.enterprise.context.Dependent;
045
046@Dependent
047public class CreateCommentCommand
048        extends BaseSimpleCommand<CreateCommentForm> {
049    
050    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
051    
052    static {
053        FORM_FIELD_DEFINITIONS = List.of(
054                new FieldDefinition("CommentedByUsername", FieldType.STRING, false, 1L, 80L),
055                new FieldDefinition("EntityRef", FieldType.ENTITY_REF, true, null, null),
056                new FieldDefinition("CommentTypeName", FieldType.ENTITY_NAME, true, null, null),
057                new FieldDefinition("LanguageIsoName", FieldType.ENTITY_NAME, false, null, null),
058                new FieldDefinition("Description", FieldType.STRING, false, 1L, 132L),
059                new FieldDefinition("MimeTypeName", FieldType.MIME_TYPE, true, null, null),
060                new FieldDefinition("WorkflowEntranceName", FieldType.ENTITY_NAME, false, null, null),
061                new FieldDefinition("ClobComment", FieldType.STRING, false, 1L, null),
062                new FieldDefinition("StringComment", FieldType.STRING, false, 1L, 512L)
063                // BlobComment is not validated
064                );
065    }
066    
067    /** Creates a new instance of CreateCommentCommand */
068    public CreateCommentCommand() {
069        super(null, FORM_FIELD_DEFINITIONS, false);
070    }
071    
072    protected String createComment(EntityInstanceControl entityInstanceControl, CommentControl commentControl, CommentType commentType, EntityInstance commentedEntityInstance, Language language, MimeType mimeType,
073            ByteArray blobComment, String clobComment, String stringComment) {
074        var sequenceControl = Session.getModelController(SequenceControl.class);
075        BasePK createdBy = getPartyPK();
076        EntityInstance commentedByEntityInstance = null;
077        String commentName = null;
078        var commentedByUsername = form.getCommentedByUsername();
079        var workflowEntranceName = form.getWorkflowEntranceName();
080        var workflowEntrance = commentType.getLastDetail().getWorkflowEntrance();
081
082        if(commentedByUsername != null) {
083            var userControl = getUserControl();
084            var userLogin = userControl.getUserLoginByUsername(commentedByUsername);
085
086            if(userLogin != null) {
087                commentedByEntityInstance = entityInstanceControl.getEntityInstanceByBasePK(userLogin.getPartyPK());
088            } else {
089                addExecutionError(ExecutionErrors.UnknownRatedByUsername.name(), commentedByUsername);
090            }
091        } else {
092            commentedByEntityInstance = entityInstanceControl.getEntityInstanceByBasePK(createdBy);
093        }
094
095        if(!hasExecutionErrors() && (workflowEntranceName != null && workflowEntrance != null)) {
096            var workflowControl = Session.getModelController(WorkflowControl.class);
097
098            workflowEntrance = workflowControl.getWorkflowEntranceByName(workflowEntrance.getLastDetail().getWorkflow(),
099                    workflowEntranceName);
100
101            if(workflowEntrance == null) {
102                addExecutionError(ExecutionErrors.UnknownWorkflowEntranceName.name(), workflowEntranceName);
103            }
104        }
105
106        if(!hasExecutionErrors()) {
107            var description = form.getDescription();
108            var commentSequence = commentType.getLastDetail().getCommentSequence();
109
110            if(commentSequence == null) {
111                commentSequence = sequenceControl.getDefaultSequenceUsingNames(SequenceTypes.COMMENT.name());
112            }
113
114            commentName = SequenceGeneratorLogic.getInstance().getNextSequenceValue(commentSequence);
115
116            var comment = commentControl.createComment(commentName, commentType, commentedEntityInstance,
117                    commentedByEntityInstance, language == null? getPreferredLanguage(): language, description, mimeType, createdBy);
118
119            if(blobComment != null) {
120                commentControl.createCommentBlob(comment, blobComment, createdBy);
121            } else if(clobComment != null) {
122                commentControl.createCommentClob(comment, clobComment, createdBy);
123            } else if(stringComment != null) {
124                commentControl.createCommentString(comment, stringComment, createdBy);
125            }
126
127            if(workflowEntrance != null) {
128                var workflowControl = Session.getModelController(WorkflowControl.class);
129                var entityInstance = entityInstanceControl.getEntityInstanceByBasePK(comment.getPrimaryKey());
130
131                // TODO: WorkEffort should be created for addEntityToWorkflow
132                workflowControl.addEntityToWorkflow(workflowEntrance, entityInstance, null, null, createdBy);
133            }
134        }
135
136        return commentName;
137    }
138
139    @Override
140    protected BaseResult execute() {
141        var result = CommentResultFactory.getCreateCommentResult();
142        var entityInstanceControl = Session.getModelController(EntityInstanceControl.class);
143        String commentName = null;
144        var entityRef = form.getEntityRef();
145        var commentedEntityInstance = entityInstanceControl.getEntityInstanceByEntityRef(entityRef);
146
147        if(commentedEntityInstance != null) {
148            var commentControl = Session.getModelController(CommentControl.class);
149            var commentTypeName = form.getCommentTypeName();
150            var commentType = commentControl.getCommentTypeByName(commentedEntityInstance.getEntityType(),
151                    commentTypeName);
152
153            if(commentType != null) {
154                var partyControl = Session.getModelController(PartyControl.class);
155                var languageIsoName = form.getLanguageIsoName();
156                var language = languageIsoName == null? null: partyControl.getLanguageByIsoName(languageIsoName);
157
158                if(languageIsoName == null || language != null) {
159                    var mimeTypeName = form.getMimeTypeName();
160
161                    if(mimeTypeName == null) {
162                        var commentString = form.getStringComment();
163
164                        if(commentString != null) {
165                            commentName = createComment(entityInstanceControl, commentControl, commentType, commentedEntityInstance, language, null, null,
166                                    null, commentString);
167                        } else {
168                            addExecutionError(ExecutionErrors.MissingStringComment.name());
169                        }
170                    } else {
171                        var mimeTypeControl = Session.getModelController(MimeTypeControl.class);
172                        var mimeType = mimeTypeControl.getMimeTypeByName(mimeTypeName);
173
174                        if(mimeType != null) {
175                            var entityAttributeType = mimeType.getLastDetail().getEntityAttributeType();
176                            var entityAttributeTypeName = entityAttributeType.getEntityAttributeTypeName();
177
178                            if(entityAttributeTypeName.equals(EntityAttributeTypes.BLOB.name())) {
179                                var blobComment = form.getBlobComment();
180
181                                if(blobComment != null) {
182                                    commentName = createComment(entityInstanceControl, commentControl, commentType, commentedEntityInstance,
183                                            language, mimeType, blobComment, null, null);
184                                } else {
185                                    addExecutionError(ExecutionErrors.MissingBlobComment.name());
186                                }
187                            } else if(entityAttributeTypeName.equals(EntityAttributeTypes.CLOB.name())) {
188                                var clobComment = form.getClobComment();
189
190                                if(clobComment != null) {
191                                    commentName = createComment(entityInstanceControl, commentControl, commentType, commentedEntityInstance,
192                                            language, mimeType, null, clobComment, null);
193                                } else {
194                                    addExecutionError(ExecutionErrors.MissingClobComment.name());
195                                }
196                            } else {
197                                addExecutionError(ExecutionErrors.UnknownEntityAttributeTypeName.name(), entityAttributeTypeName);
198                            }
199                        } else {
200                            addExecutionError(ExecutionErrors.UnknownMimeTypeName.name(), mimeTypeName);
201                        }
202                    }
203                } else {
204                    addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), languageIsoName);
205                }
206            } else {
207                addExecutionError(ExecutionErrors.UnknownCommentTypeName.name(), commentTypeName);
208            }
209        } else {
210            addExecutionError(ExecutionErrors.UnknownEntityRef.name(), entityRef);
211        }
212        
213        result.setCommentName(commentName);
214        
215        return result;
216    }
217    
218}