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.util.server.persistence; 018 019import com.echothree.model.control.core.common.ComponentVendors; 020import com.echothree.model.control.core.common.EntityTypes; 021import com.echothree.model.control.security.common.SecurityRoleGroups; 022import com.echothree.model.control.security.common.SecurityRoles; 023import com.echothree.model.control.security.server.logic.SecurityRoleLogic; 024import com.echothree.model.control.sequence.common.SequenceTypes; 025import com.echothree.model.control.sequence.server.logic.SequenceGeneratorLogic; 026import com.echothree.model.control.warehouse.server.control.WarehouseControl; 027import com.echothree.model.data.communication.common.pk.CommunicationEventPK; 028import com.echothree.model.data.communication.server.factory.CommunicationEventFactory; 029import com.echothree.model.data.contactlist.common.pk.PartyContactListPK; 030import com.echothree.model.data.contactlist.server.factory.PartyContactListFactory; 031import com.echothree.model.data.core.common.pk.ComponentVendorPK; 032import com.echothree.model.data.core.common.pk.EntityTypePK; 033import com.echothree.model.data.core.common.pk.MimeTypePK; 034import com.echothree.model.data.core.server.entity.EntityInstance; 035import com.echothree.model.data.core.server.factory.ComponentVendorFactory; 036import com.echothree.model.data.core.server.factory.EntityTypeFactory; 037import com.echothree.model.data.core.server.factory.MimeTypeFactory; 038import com.echothree.model.data.forum.common.pk.ForumGroupPK; 039import com.echothree.model.data.forum.common.pk.ForumMessagePK; 040import com.echothree.model.data.forum.common.pk.ForumPK; 041import com.echothree.model.data.forum.common.pk.ForumThreadPK; 042import com.echothree.model.data.forum.server.factory.ForumFactory; 043import com.echothree.model.data.forum.server.factory.ForumGroupFactory; 044import com.echothree.model.data.forum.server.factory.ForumMessageFactory; 045import com.echothree.model.data.forum.server.factory.ForumThreadFactory; 046import com.echothree.model.data.item.common.pk.ItemDescriptionPK; 047import com.echothree.model.data.item.common.pk.ItemPK; 048import com.echothree.model.data.item.server.factory.ItemDescriptionFactory; 049import com.echothree.model.data.item.server.factory.ItemFactory; 050import com.echothree.model.data.party.server.entity.Party; 051import com.echothree.model.data.subscription.common.pk.SubscriptionPK; 052import com.echothree.model.data.subscription.server.factory.SubscriptionFactory; 053import com.echothree.model.data.training.common.pk.PartyTrainingClassPK; 054import com.echothree.model.data.training.common.pk.TrainingClassPK; 055import com.echothree.model.data.training.server.factory.PartyTrainingClassFactory; 056import com.echothree.model.data.training.server.factory.TrainingClassFactory; 057import com.echothree.model.data.vendor.common.pk.VendorItemPK; 058import com.echothree.model.data.vendor.server.factory.VendorItemFactory; 059import com.echothree.model.data.warehouse.common.pk.LocationPK; 060import com.echothree.model.data.warehouse.server.factory.LocationFactory; 061import com.echothree.util.common.persistence.EntityNames; 062import com.echothree.util.common.persistence.Names; 063import com.echothree.util.common.persistence.Targets; 064import com.echothree.util.common.transfer.MapWrapper; 065import com.echothree.util.server.persistence.translator.ComponentVendorTranslator; 066import com.echothree.util.server.persistence.translator.EntityInstanceAndNames; 067import com.echothree.util.server.persistence.translator.EntityInstanceTranslator; 068import com.echothree.util.server.persistence.translator.InvoiceNameTranslator; 069import com.echothree.util.server.persistence.translator.OrderNameTranslator; 070import com.echothree.util.server.persistence.translator.PartyNameTranslator; 071import com.echothree.util.server.persistence.translator.SequenceTypeTranslator; 072import java.util.Collections; 073import java.util.HashMap; 074import java.util.Map; 075 076public class EntityNamesUtils { 077 078 private EntityNamesUtils() { 079 super(); 080 } 081 082 private static class EntityNamesUtilsHolder { 083 static EntityNamesUtils instance = new EntityNamesUtils(); 084 } 085 086 public static EntityNamesUtils getInstance() { 087 return EntityNamesUtilsHolder.instance; 088 } 089 090 private final static Map<String, ComponentVendorTranslator> componentVendorTranslators = new HashMap<>(); 091 092 public static void addComponentVendorTranslator(String componentVendorName, ComponentVendorTranslator componentVendorTranslator) { 093 componentVendorTranslators.put(componentVendorName, componentVendorTranslator); 094 } 095 096 static { 097 Map<String, EntityInstanceTranslator> nameTranslators = new HashMap<>(16); 098 099 nameTranslators.put(EntityTypes.Invoice.name(), new InvoiceNameTranslator()); 100 nameTranslators.put(EntityTypes.Order.name(), new OrderNameTranslator()); 101 nameTranslators.put(EntityTypes.Party.name(), new PartyNameTranslator()); 102 103 nameTranslators.put(EntityTypes.Item.name(), (final EntityInstance entityInstance) -> { 104 var itemDetail = ItemFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 105 new ItemPK(entityInstance.getEntityUniqueId())).getLastDetail(); 106 var names = new MapWrapper<String>(1); 107 108 names.put(Names.ItemName.name(), itemDetail.getItemName()); 109 110 return new EntityNames(Targets.Item.name(), names); 111 }); 112 113 nameTranslators.put(EntityTypes.ItemDescription.name(), (final EntityInstance entityInstance) -> { 114 var itemDescriptionDetail = ItemDescriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 115 new ItemDescriptionPK(entityInstance.getEntityUniqueId())).getLastDetail(); 116 var names = new MapWrapper<String>(3); 117 118 names.put(Names.ItemDescriptionTypeName.name(), itemDescriptionDetail.getItemDescriptionType().getLastDetail().getItemDescriptionTypeName()); 119 names.put(Names.ItemName.name(), itemDescriptionDetail.getItem().getLastDetail().getItemName()); 120 names.put(Names.LanguageIsoName.name(), itemDescriptionDetail.getLanguage().getLanguageIsoName()); 121 122 return new EntityNames(Targets.ItemDescription.name(), names); 123 }); 124 125 nameTranslators.put(EntityTypes.ForumGroup.name(), (final EntityInstance entityInstance) -> { 126 var forumGroupDetail = ForumGroupFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 127 new ForumGroupPK(entityInstance.getEntityUniqueId())).getLastDetail(); 128 var names = new MapWrapper<String>(1); 129 130 names.put(Names.ForumGroupName.name(), forumGroupDetail.getForumGroupName()); 131 132 return new EntityNames(Targets.ForumGroup.name(), names); 133 }); 134 135 nameTranslators.put(EntityTypes.Forum.name(), (final EntityInstance entityInstance) -> { 136 var forumDetail = ForumFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 137 new ForumPK(entityInstance.getEntityUniqueId())).getLastDetail(); 138 var names = new MapWrapper<String>(1); 139 140 names.put(Names.ForumName.name(), forumDetail.getForumName()); 141 142 return new EntityNames(Targets.Forum.name(), names); 143 }); 144 145 nameTranslators.put(EntityTypes.ForumMessage.name(), (final EntityInstance entityInstance) -> { 146 var forumMessageDetail = ForumMessageFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 147 new ForumMessagePK(entityInstance.getEntityUniqueId())).getLastDetail(); 148 var names = new MapWrapper<String>(1); 149 150 names.put(Names.ForumMessageName.name(), forumMessageDetail.getForumMessageName()); 151 152 return new EntityNames(Targets.ForumMessage.name(), names); 153 }); 154 155 nameTranslators.put(EntityTypes.ForumThread.name(), (final EntityInstance entityInstance) -> { 156 var forumThreadDetail = ForumThreadFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 157 new ForumThreadPK(entityInstance.getEntityUniqueId())).getLastDetail(); 158 var names = new MapWrapper<String>(1); 159 160 names.put(Names.ForumThreadName.name(), forumThreadDetail.getForumThreadName()); 161 162 return new EntityNames(Targets.ForumThread.name(), names); 163 }); 164 165 nameTranslators.put(EntityTypes.TrainingClass.name(), (final EntityInstance entityInstance) -> { 166 var trainingClassDetail = TrainingClassFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 167 new TrainingClassPK(entityInstance.getEntityUniqueId())).getLastDetail(); 168 var names = new MapWrapper<String>(1); 169 170 names.put(Names.TrainingClassName.name(), trainingClassDetail.getTrainingClassName()); 171 172 return new EntityNames(Targets.TrainingClass.name(), names); 173 }); 174 175 nameTranslators.put(EntityTypes.PartyTrainingClass.name(), (final EntityInstance entityInstance) -> { 176 var partyTrainingClassDetail = PartyTrainingClassFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 177 new PartyTrainingClassPK(entityInstance.getEntityUniqueId())).getLastDetail(); 178 var names = new MapWrapper<String>(1); 179 180 names.put(Names.PartyTrainingClassName.name(), partyTrainingClassDetail.getPartyTrainingClassName()); 181 182 return new EntityNames(Targets.PartyTrainingClass.name(), names); 183 }); 184 185 nameTranslators.put(EntityTypes.CommunicationEvent.name(), (final EntityInstance entityInstance) -> { 186 var communicationEventDetail = CommunicationEventFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 187 new CommunicationEventPK(entityInstance.getEntityUniqueId())).getLastDetail(); 188 var names = new MapWrapper<String>(1); 189 190 names.put(Names.CommunicationEventName.name(), communicationEventDetail.getCommunicationEventName()); 191 192 return new EntityNames(Targets.CommunicationEvent.name(), names); 193 }); 194 195 nameTranslators.put(EntityTypes.VendorItem.name(), (final EntityInstance entityInstance) -> { 196 var vendorItemDetail = VendorItemFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 197 new VendorItemPK(entityInstance.getEntityUniqueId())).getLastDetail(); 198 var names = new MapWrapper<String>(2); 199 200 names.put(Names.VendorItemName.name(), vendorItemDetail.getVendorItemName()); 201 names.put(Names.PartyName.name(), vendorItemDetail.getVendorParty().getLastDetail().getPartyName()); 202 203 return new EntityNames(Targets.VendorItem.name(), names); 204 }); 205 206 nameTranslators.put(EntityTypes.PartyContactList.name(), (final EntityInstance entityInstance) -> { 207 var partyContactListDetail = PartyContactListFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 208 new PartyContactListPK(entityInstance.getEntityUniqueId())).getLastDetail(); 209 var names = new MapWrapper<String>(2); 210 211 names.put(Names.PartyName.name(), partyContactListDetail.getParty().getLastDetail().getPartyName()); 212 names.put(Names.ContactListName.name(), partyContactListDetail.getContactList().getLastDetail().getContactListName()); 213 214 return new EntityNames(Targets.PartyContactList.name(), names); 215 }); 216 217 nameTranslators.put(EntityTypes.Subscription.name(), (final EntityInstance entityInstance) -> { 218 var subscription = SubscriptionFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 219 new SubscriptionPK(entityInstance.getEntityUniqueId())); 220 var names = new MapWrapper<String>(1); 221 222 names.put(Names.SubscriptionName.name(), subscription.getLastDetail().getSubscriptionName()); 223 224 return new EntityNames(Targets.Subscription.name(), names); 225 }); 226 227 nameTranslators.put(EntityTypes.MimeType.name(), (final EntityInstance entityInstance) -> { 228 var mimeType = MimeTypeFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 229 new MimeTypePK(entityInstance.getEntityUniqueId())); 230 var names = new MapWrapper<String>(1); 231 232 names.put(Names.MimeTypeName.name(), mimeType.getLastDetail().getMimeTypeName()); 233 234 return new EntityNames(Targets.MimeType.name(), names); 235 }); 236 237 nameTranslators.put(EntityTypes.Location.name(), (final EntityInstance entityInstance) -> { 238 var warehouseControl = Session.getModelController(WarehouseControl.class); 239 var location = LocationFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 240 new LocationPK(entityInstance.getEntityUniqueId())); 241 var names = new MapWrapper<String>(2); 242 var locationDetail = location.getLastDetail(); 243 244 names.put(Names.WarehouseName.name(), warehouseControl.getWarehouse(locationDetail.getWarehouseParty()).getWarehouseName()); 245 names.put(Names.LocationName.name(), locationDetail.getLocationName()); 246 247 return new EntityNames(Targets.Location.name(), names); 248 }); 249 250 nameTranslators.put(EntityTypes.ComponentVendor.name(), (final EntityInstance entityInstance) -> { 251 var componentVendor = ComponentVendorFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 252 new ComponentVendorPK(entityInstance.getEntityUniqueId())); 253 var names = new MapWrapper<String>(1); 254 255 names.put(Names.ComponentVendorName.name(), componentVendor.getLastDetail().getComponentVendorName()); 256 257 return new EntityNames(Targets.ComponentVendor.name(), names); 258 }); 259 260 nameTranslators.put(EntityTypes.EntityType.name(), (final EntityInstance entityInstance) -> { 261 var entityType = EntityTypeFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, 262 new EntityTypePK(entityInstance.getEntityUniqueId())); 263 var names = new MapWrapper<String>(2); 264 var entityTypeDetail = entityType.getLastDetail(); 265 266 names.put(Names.ComponentVendorName.name(), entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName()); 267 names.put(Names.EntityTypeName.name(), entityTypeDetail.getEntityTypeName()); 268 269 return new EntityNames(Targets.EntityType.name(), names); 270 }); 271 272 nameTranslators = Collections.unmodifiableMap(nameTranslators); 273 274 addComponentVendorTranslator(ComponentVendors.ECHO_THREE.name(), new ComponentVendorTranslator(nameTranslators)); 275 } 276 277 // Entry point from the Identify UC. Permissions have already been checked at this point. 278 public EntityInstanceAndNames getEntityNames(final EntityInstance entityInstance) { 279 EntityNames result = null; 280 var entityType = entityInstance.getEntityType(); 281 var componentVendor = entityType.getLastDetail().getComponentVendor(); 282 var componentVendorName = componentVendor.getLastDetail().getComponentVendorName(); 283 284 ComponentVendorTranslator componentVendorTranslator = componentVendorTranslators.get(componentVendorName); 285 286 if(componentVendorTranslator != null) { 287 EntityInstanceTranslator nameTranslator = componentVendorTranslator.getNameTranslators().get(entityType.getLastDetail().getEntityTypeName()); 288 289 if(nameTranslator != null) { 290 result = nameTranslator.getNames(entityInstance); 291 } 292 } 293 294 return result == null ? null : new EntityInstanceAndNames(entityInstance, result); 295 } 296 297 private final static Map<String, SequenceTypeTranslator> sequenceTypeTranslators; 298 299 private final static InvoiceNameTranslator INVOICE_NAME_TRANSLATOR = new InvoiceNameTranslator(); 300 private final static OrderNameTranslator ORDER_NAME_TRANSLATOR = new OrderNameTranslator(); 301 private final static PartyNameTranslator PARTY_NAME_TRANSLATOR = new PartyNameTranslator(); 302 303 static { 304 var sequenceTypeTranslatorsMap = new HashMap<String, SequenceTypeTranslator>(7); 305 306 sequenceTypeTranslatorsMap.put(SequenceTypes.PURCHASE_INVOICE.name(), INVOICE_NAME_TRANSLATOR); 307 sequenceTypeTranslatorsMap.put(SequenceTypes.SALES_INVOICE.name(), INVOICE_NAME_TRANSLATOR); 308 sequenceTypeTranslatorsMap.put(SequenceTypes.PURCHASE_ORDER.name(), ORDER_NAME_TRANSLATOR); 309 sequenceTypeTranslatorsMap.put(SequenceTypes.SALES_ORDER.name(), ORDER_NAME_TRANSLATOR); 310 sequenceTypeTranslatorsMap.put(SequenceTypes.WISHLIST.name(), ORDER_NAME_TRANSLATOR); 311 sequenceTypeTranslatorsMap.put(SequenceTypes.CUSTOMER.name(), PARTY_NAME_TRANSLATOR); 312 sequenceTypeTranslatorsMap.put(SequenceTypes.EMPLOYEE.name(), PARTY_NAME_TRANSLATOR); 313 314 sequenceTypeTranslators = Collections.unmodifiableMap(sequenceTypeTranslatorsMap); 315 } 316 317 private EntityInstanceAndNames getEntityNames(final String sequenceTypeName, final String value, 318 final boolean includeEntityInstance) { 319 EntityInstanceAndNames result = null; 320 var sequenceTypeTranslator = sequenceTypeTranslators.get(sequenceTypeName); 321 322 if(sequenceTypeTranslator != null) { 323 result = sequenceTypeTranslator.getNames(sequenceTypeName, value, includeEntityInstance); 324 } 325 326 return result; 327 } 328 329 // Entry point from the Identify UC. Permissions have NOT been checked at this point. 330 public EntityInstanceAndNames getEntityNames(final Party requestingParty, final String value, final boolean includeEntityInstance) { 331 EntityInstanceAndNames result = null; 332 var sequenceType = SequenceGeneratorLogic.getInstance().identifySequenceType(value); 333 334 if(sequenceType != null) { 335 var sequenceTypeName = sequenceType.getLastDetail().getSequenceTypeName(); 336 boolean hasAccess = false; 337 338 if(sequenceTypeName.equals(SequenceTypes.PURCHASE_INVOICE.name()) 339 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 340 SecurityRoleGroups.PurchaseInvoice.name(), SecurityRoles.Search.name())) { 341 hasAccess = true; 342 } else if(sequenceTypeName.equals(SequenceTypes.SALES_INVOICE.name()) 343 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 344 SecurityRoleGroups.SalesOrder.name(), SecurityRoles.Search.name())) { 345 hasAccess = true; 346 } else if(sequenceTypeName.equals(SequenceTypes.PURCHASE_ORDER.name()) 347 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 348 SecurityRoleGroups.PurchaseOrder.name(), SecurityRoles.Search.name())) { 349 hasAccess = true; 350 } else if(sequenceTypeName.equals(SequenceTypes.SALES_ORDER.name()) 351 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 352 SecurityRoleGroups.SalesOrder.name(), SecurityRoles.Search.name())) { 353 hasAccess = true; 354 } else if(sequenceTypeName.equals(SequenceTypes.WISHLIST.name()) 355 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 356 SecurityRoleGroups.Wishlist.name(), SecurityRoles.Search.name())) { 357 hasAccess = true; 358 } else if(sequenceTypeName.equals(SequenceTypes.CUSTOMER.name()) 359 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 360 SecurityRoleGroups.Customer.name(), SecurityRoles.Search.name())) { 361 hasAccess = true; 362 } else if(sequenceTypeName.equals(SequenceTypes.EMPLOYEE.name()) 363 && SecurityRoleLogic.getInstance().hasSecurityRoleUsingNames(null, requestingParty, 364 SecurityRoleGroups.Employee.name(), SecurityRoles.Search.name())) { 365 hasAccess = true; 366 } 367 368 result = hasAccess ? getEntityNames(sequenceTypeName, value, includeEntityInstance) : null; 369 } 370 371 return result; 372 } 373 374}