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