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.item.server.command;
018
019import com.echothree.control.user.item.common.form.CreateItemDescriptionForm;
020import com.echothree.control.user.item.common.result.ItemResultFactory;
021import com.echothree.model.control.core.common.EntityAttributeTypes;
022import com.echothree.model.control.core.common.MimeTypeUsageTypes;
023import com.echothree.model.control.core.server.control.MimeTypeControl;
024import com.echothree.model.control.item.server.control.ItemControl;
025import com.echothree.model.control.item.server.logic.ItemDescriptionLogic;
026import com.echothree.model.control.item.server.logic.ItemDescriptionLogic.ImageDimensions;
027import com.echothree.model.control.party.common.PartyTypes;
028import com.echothree.model.control.party.server.control.PartyControl;
029import com.echothree.model.control.security.common.SecurityRoleGroups;
030import com.echothree.model.control.security.common.SecurityRoles;
031import com.echothree.model.data.core.server.entity.MimeType;
032import com.echothree.model.data.core.server.entity.MimeTypeUsageType;
033import com.echothree.model.data.item.server.entity.Item;
034import com.echothree.model.data.item.server.entity.ItemDescription;
035import com.echothree.model.data.item.server.entity.ItemDescriptionType;
036import com.echothree.model.data.item.server.entity.ItemImageType;
037import com.echothree.model.data.party.server.entity.Language;
038import com.echothree.model.data.user.common.pk.UserVisitPK;
039import com.echothree.util.common.command.BaseResult;
040import com.echothree.util.common.message.ExecutionErrors;
041import com.echothree.util.common.persistence.BasePK;
042import com.echothree.util.common.persistence.type.ByteArray;
043import com.echothree.util.common.validation.FieldDefinition;
044import com.echothree.util.common.validation.FieldType;
045import com.echothree.util.server.control.BaseSimpleCommand;
046import com.echothree.util.server.control.CommandSecurityDefinition;
047import com.echothree.util.server.control.PartyTypeDefinition;
048import com.echothree.util.server.control.SecurityRoleDefinition;
049import com.echothree.util.server.persistence.Session;
050import java.util.List;
051import javax.enterprise.context.Dependent;
052
053@Dependent
054public class CreateItemDescriptionCommand
055        extends BaseSimpleCommand<CreateItemDescriptionForm> {
056    
057    private final static CommandSecurityDefinition COMMAND_SECURITY_DEFINITION;
058    private final static List<FieldDefinition> FORM_FIELD_DEFINITIONS;
059    
060    static {
061        COMMAND_SECURITY_DEFINITION = new CommandSecurityDefinition(List.of(
062                new PartyTypeDefinition(PartyTypes.UTILITY.name(), null),
063                new PartyTypeDefinition(PartyTypes.EMPLOYEE.name(), List.of(
064                        new SecurityRoleDefinition(SecurityRoleGroups.ItemDescription.name(), SecurityRoles.Create.name())
065                        ))
066                ));
067
068        FORM_FIELD_DEFINITIONS = List.of(
069                new FieldDefinition("ItemName", FieldType.ENTITY_NAME, true, null, null),
070                new FieldDefinition("ItemDescriptionTypeName", FieldType.ENTITY_NAME, true, null, null),
071                new FieldDefinition("LanguageIsoName", FieldType.ENTITY_NAME, true, null, null),
072                new FieldDefinition("MimeTypeName", FieldType.MIME_TYPE, false, null, null),
073                new FieldDefinition("ItemImageTypeName", FieldType.ENTITY_NAME, false, null, null),
074                new FieldDefinition("ClobDescription", FieldType.STRING, false, 1L, null),
075                new FieldDefinition("StringDescription", FieldType.STRING, false, 1L, 512L)
076                );
077    }
078    
079    /** Creates a new instance of CreateItemDescriptionCommand */
080    public CreateItemDescriptionCommand() {
081        super(COMMAND_SECURITY_DEFINITION, FORM_FIELD_DEFINITIONS, false);
082    }
083
084    protected ItemDescription createItemDescription(ItemControl itemControl, ItemDescriptionType itemDescriptionType, Item item, Language language, MimeType mimeType,
085            BasePK createdBy, ByteArray blobDescription, String clobDescription, String stringDescription, MimeTypeUsageType mimeTypeUsageType) {
086        ItemImageType itemImageType = null;
087        ImageDimensions imageDimensions = null;
088        ItemDescription itemDescription = null;
089
090        if(mimeTypeUsageType != null) {
091            var mimeTypeUsageTypeName = mimeTypeUsageType.getMimeTypeUsageTypeName();
092
093            if(mimeTypeUsageTypeName.equals(MimeTypeUsageTypes.IMAGE.name())) {
094                var itemImageTypeName = form.getItemImageTypeName();
095
096                if(itemImageTypeName != null) {
097                    itemImageType = itemControl.getItemImageTypeByName(itemImageTypeName);
098
099                    if(itemImageType != null) {
100                        // Only works for images coming in as BLOBs.
101                        if(blobDescription != null) {
102                            imageDimensions = ItemDescriptionLogic.getInstance().getImageDimensions(mimeType.getLastDetail().getMimeTypeName(), blobDescription);
103                        }
104
105                        if(imageDimensions == null) {
106                            addExecutionError(ExecutionErrors.InvalidImage.name());
107                        } else {
108                            var itemImageDescriptionType = itemControl.getItemImageDescriptionType(itemDescriptionType);
109
110                            if(itemImageDescriptionType != null) {
111                                var minimumHeight = itemImageDescriptionType.getMinimumHeight();
112                                var minimumWidth = itemImageDescriptionType.getMinimumWidth();
113                                var maximumHeight = itemImageDescriptionType.getMaximumHeight();
114                                var maximumWidth = itemImageDescriptionType.getMaximumWidth();
115                                var imageHeight = imageDimensions.getHeight();
116                                var imageWidth = imageDimensions.getWidth();
117
118                                if(minimumHeight != null && imageHeight < minimumHeight) {
119                                    addExecutionError(ExecutionErrors.ImageHeightLessThanMinimum.name(), imageHeight.toString(), minimumHeight.toString());
120                                }
121
122                                if(minimumWidth != null && imageWidth < minimumWidth) {
123                                    addExecutionError(ExecutionErrors.ImageWidthLessThanMinimum.name(), imageWidth.toString(), minimumWidth.toString());
124                                }
125
126                                if(maximumHeight != null && imageHeight > maximumHeight) {
127                                    addExecutionError(ExecutionErrors.ImageHeightGreaterThanMaximum.name(), imageHeight.toString(), maximumHeight.toString());
128                                }
129
130                                if(maximumWidth != null && imageWidth > maximumWidth) {
131                                    addExecutionError(ExecutionErrors.ImageWidthGreaterThanMaximum.name(), imageWidth.toString(), maximumWidth.toString());
132                                }
133                            }
134                        }
135                    } else {
136                      addExecutionError(ExecutionErrors.UnknownItemImageTypeName.name(), itemImageTypeName);
137                    }
138                } else {
139                      addExecutionError(ExecutionErrors.MissingRequiredItemImageTypeName.name());
140                }
141            }
142        }
143
144        if(!hasExecutionErrors()) {
145            itemDescription = itemControl.createItemDescription(itemDescriptionType, item, language, mimeType,
146                    createdBy);
147
148            if(blobDescription != null) {
149                itemControl.createItemBlobDescription(itemDescription, blobDescription, createdBy);
150            } else if(clobDescription != null) {
151                itemControl.createItemClobDescription(itemDescription, clobDescription, createdBy);
152            } else if(stringDescription != null) {
153                itemControl.createItemStringDescription(itemDescription, stringDescription, createdBy);
154            }
155
156            if(imageDimensions != null) {
157                itemControl.createItemImageDescription(itemDescription, itemImageType, imageDimensions.getHeight(), imageDimensions.getWidth(), false,
158                        createdBy);
159
160                ItemDescriptionLogic.getInstance().deleteItemImageDescriptionChildren(itemDescription, createdBy);
161            }
162        }
163
164        return itemDescription;
165    }
166    
167    @Override
168    protected BaseResult execute() {
169        var result = ItemResultFactory.getCreateItemDescriptionResult();
170        var itemControl = Session.getModelController(ItemControl.class);
171        var itemName = form.getItemName();
172        var item = itemControl.getItemByName(itemName);
173        ItemDescription itemDescription = null;
174        
175        if(item != null) {
176            var itemDescriptionTypeName = form.getItemDescriptionTypeName();
177            var itemDescriptionType = itemControl.getItemDescriptionTypeByName(itemDescriptionTypeName);
178            
179            if(itemDescriptionType != null) {
180                var partyControl = Session.getModelController(PartyControl.class);
181                var languageIsoName = form.getLanguageIsoName();
182                var language = partyControl.getLanguageByIsoName(languageIsoName);
183                
184                if(language != null) {
185                    BasePK createdBy = getPartyPK();
186
187                    itemDescription = itemControl.getItemDescription(itemDescriptionType, item, language);
188                    
189                    if(itemDescription == null) {
190                        var mimeTypeName = form.getMimeTypeName();
191                        
192                        if(mimeTypeName == null) {
193                            if(itemDescriptionType.getLastDetail().getMimeTypeUsageType() == null) {
194                                var stringDescription = form.getStringDescription();
195                                
196                                if(stringDescription != null) {
197                                    itemDescription = createItemDescription(itemControl, itemDescriptionType, item, language, null, createdBy, null,
198                                            null, stringDescription, null);
199                                } else {
200                                    addExecutionError(ExecutionErrors.MissingStringDescription.name());
201                                }
202                            } else {
203                                // No mimeTypeName was supplied, but yet we required a MimeTypeUsageType
204                                addExecutionError(ExecutionErrors.InvalidMimeType.name());
205                            }
206                        } else {
207                            var mimeTypeControl = Session.getModelController(MimeTypeControl.class);
208                            var mimeType = mimeTypeControl.getMimeTypeByName(mimeTypeName);
209                            
210                            if(mimeType != null) {
211                                var mimeTypeUsageType = itemDescriptionType.getLastDetail().getMimeTypeUsageType();
212                                
213                                if(mimeTypeUsageType != null) {
214                                    var mimeTypeUsage = mimeTypeControl.getMimeTypeUsage(mimeType, mimeTypeUsageType);
215                                    
216                                    if(mimeTypeUsage != null) {
217                                        var entityAttributeType = mimeType.getLastDetail().getEntityAttributeType();
218                                        var entityAttributeTypeName = entityAttributeType.getEntityAttributeTypeName();
219                                        
220                                        if(entityAttributeTypeName.equals(EntityAttributeTypes.BLOB.name())) {
221                                            var blobDescription = form.getBlobDescription();
222                                            
223                                            if(blobDescription != null) {
224                                                itemDescription = createItemDescription(itemControl, itemDescriptionType, item, language, mimeType,
225                                                        createdBy, blobDescription, null, null, mimeTypeUsageType);
226                                            } else {
227                                                addExecutionError(ExecutionErrors.MissingBlobDescription.name());
228                                            }
229                                        } else if(entityAttributeTypeName.equals(EntityAttributeTypes.CLOB.name())) {
230                                            var clobDescription = form.getClobDescription();
231                                            
232                                            if(clobDescription != null) {
233                                                itemDescription = createItemDescription(itemControl, itemDescriptionType, item, language, mimeType,
234                                                        createdBy, null, clobDescription, null, mimeTypeUsageType);
235                                            } else {
236                                                addExecutionError(ExecutionErrors.MissingClobDescription.name());
237                                            }
238                                        } else {
239                                            addExecutionError(ExecutionErrors.UnknownEntityAttributeTypeName.name(), entityAttributeTypeName);
240                                        }
241                                    } else {
242                                        addExecutionError(ExecutionErrors.UnknownMimeTypeUsage.name());
243                                    }
244                                } else {
245                                    // mimeTypeName was supplied, and there shouldn't be one
246                                    addExecutionError(ExecutionErrors.InvalidMimeType.name());
247                                }
248                            } else {
249                                addExecutionError(ExecutionErrors.UnknownMimeTypeName.name(), mimeTypeName);
250                            }
251                        }
252                    } else {
253                        addExecutionError(ExecutionErrors.DuplicateItemDescription.name(), itemName, itemDescriptionTypeName, languageIsoName);
254                    }
255                } else {
256                    addExecutionError(ExecutionErrors.UnknownLanguageIsoName.name(), languageIsoName);
257                }
258            } else {
259                addExecutionError(ExecutionErrors.UnknownItemDescriptionTypeName.name(), itemDescriptionTypeName);
260            }
261        } else {
262            addExecutionError(ExecutionErrors.UnknownItemName.name(), itemName);
263        }
264        
265        if(itemDescription != null) {
266            var itemDescriptionDetail = itemDescription.getLastDetail();
267
268            result.setItemName(itemDescriptionDetail.getItem().getLastDetail().getItemName());
269            result.setItemDescriptionTypeName(itemDescriptionDetail.getItemDescriptionType().getLastDetail().getItemDescriptionTypeName());
270            result.setLanguageIsoName(itemDescriptionDetail.getLanguage().getLanguageIsoName());
271            result.setEntityRef(itemDescription.getPrimaryKey().getEntityRef());
272        }
273
274        return result;
275    }
276    
277}