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}