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