001// -------------------------------------------------------------------------------- 002// Copyright 2002-2025 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.model.control.core.server.logic; 018 019import com.echothree.control.user.core.common.spec.EntityRefSpec; 020import com.echothree.control.user.core.common.spec.UniversalEntitySpec; 021import com.echothree.control.user.core.common.spec.UuidSpec; 022import com.echothree.model.control.core.common.ComponentVendors; 023import com.echothree.model.control.core.common.EventTypes; 024import com.echothree.model.control.core.common.exception.DeletedEntityRefException; 025import com.echothree.model.control.core.common.exception.DeletedUuidException; 026import com.echothree.model.control.core.common.exception.InvalidComponentVendorException; 027import com.echothree.model.control.core.common.exception.InvalidEntityTypeException; 028import com.echothree.model.control.core.common.exception.InvalidParameterCountException; 029import com.echothree.model.control.core.common.exception.UnknownEntityRefException; 030import com.echothree.model.control.core.common.exception.UnknownUuidException; 031import com.echothree.model.control.core.server.control.EntityInstanceControl; 032import com.echothree.model.control.core.server.control.EventControl; 033import com.echothree.model.data.core.server.entity.EntityInstance; 034import com.echothree.model.data.core.server.entity.EntityType; 035import com.echothree.util.common.message.ExecutionErrors; 036import com.echothree.util.common.persistence.BasePK; 037import com.echothree.util.server.control.BaseLogic; 038import com.echothree.util.server.message.ExecutionErrorAccumulator; 039import com.echothree.util.server.persistence.EntityIdGenerator; 040import com.echothree.util.server.persistence.Session; 041import javax.enterprise.context.ApplicationScoped; 042import javax.enterprise.inject.spi.CDI; 043import javax.inject.Inject; 044 045@ApplicationScoped 046public class EntityInstanceLogic 047 extends BaseLogic { 048 049 @Inject 050 protected EntityInstanceControl entityInstanceControl; 051 052 protected EntityInstanceLogic() { 053 super(); 054 } 055 056 public static EntityInstanceLogic getInstance() { 057 return CDI.current().select(EntityInstanceLogic.class).get(); 058 } 059 060 public EntityInstance createEntityInstance(final ExecutionErrorAccumulator eea, final EntityType entityType, 061 final BasePK createdBy) { 062 var entityTypeDetail = entityType.getLastDetail(); 063 var componentVendorName = entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(); 064 EntityInstance entityInstance = null; 065 066 if(!ComponentVendors.ECHO_THREE.name().equals(componentVendorName)) { 067 var eventControl = Session.getModelController(EventControl.class); 068 var entityTypeName = entityTypeDetail.getEntityTypeName(); 069 var entityIdGenerator = new EntityIdGenerator(componentVendorName, entityTypeName, 1); // TODO 070 var entityId = entityIdGenerator.getNextEntityId(); 071 var basePK = new BasePK(componentVendorName, entityTypeName, entityId); 072 var event = eventControl.sendEvent(basePK, EventTypes.CREATE, null, null, createdBy); 073 074 entityInstance = event.getEntityInstance(); 075 } else { 076 handleExecutionError(InvalidComponentVendorException.class, eea, ExecutionErrors.InvalidComponentVendor.name(), componentVendorName); 077 } 078 079 return entityInstance; 080 } 081 082 private boolean checkEntityTimeForDeletion(EventControl eventControl, EntityInstance entityInstance) { 083 boolean wasDeleted = false; 084 var entityTime = eventControl.getEntityTime(entityInstance); 085 086 // If the EntityTime is null, then we're not going to find a DeletedTime, which means it must exist... 087 // do not mark it as having been deleted. 088 if(entityTime != null) { 089 // Check the DeletedTime... 090 if(entityTime.getDeletedTime() != null) { 091 // It's been deleted. 092 wasDeleted = true; 093 } 094 } 095 096 return wasDeleted; 097 } 098 099 public EntityInstance getEntityInstanceByEntityRef(final ExecutionErrorAccumulator eea, final String entityRef) { 100 var entityInstance = entityInstanceControl.getEntityInstanceByEntityRef(entityRef); 101 102 if(entityInstance == null) { 103 handleExecutionError(UnknownEntityRefException.class, eea, ExecutionErrors.UnknownEntityRef.name(), entityRef); 104 } else { 105 var eventControl = Session.getModelController(EventControl.class); 106 var wasDeleted = checkEntityTimeForDeletion(eventControl, entityInstance); 107 108 if(wasDeleted) { 109 entityInstance = null; 110 handleExecutionError(DeletedEntityRefException.class, eea, ExecutionErrors.DeletedEntityRef.name(), entityRef); 111 } 112 } 113 114 115 return entityInstance; 116 } 117 118 public EntityInstance getEntityInstanceByEntityRef(final ExecutionErrorAccumulator eea, final EntityRefSpec spec) { 119 return getEntityInstanceByEntityRef(eea, spec.getEntityRef()); 120 } 121 122 public EntityInstance getEntityInstanceByUuid(final ExecutionErrorAccumulator eea, final String uuid) { 123 var entityInstance = entityInstanceControl.getEntityInstanceByUuid(uuid); 124 125 if(entityInstance == null) { 126 handleExecutionError(UnknownUuidException.class, eea, ExecutionErrors.UnknownUuid.name(), uuid); 127 } else { 128 var eventControl = Session.getModelController(EventControl.class); 129 var wasDeleted = checkEntityTimeForDeletion(eventControl, entityInstanceControl.getEntityInstanceByUuid(uuid)); 130 131 if(wasDeleted) { 132 entityInstance = null; 133 handleExecutionError(DeletedUuidException.class, eea, ExecutionErrors.DeletedUuid.name(), uuid); 134 } 135 } 136 137 return entityInstance; 138 } 139 140 public EntityInstance getEntityInstanceByUuid(final ExecutionErrorAccumulator eea, final UuidSpec spec) { 141 return getEntityInstanceByUuid(eea, spec.getUuid()); 142 } 143 144 public EntityInstance getEntityInstance(final ExecutionErrorAccumulator eea, final String entityRef, 145 final String uuid, final String componentVendorName, final String... entityTypeNames) { 146 var parameterCount = countPossibleEntitySpecs(entityRef, uuid); 147 EntityInstance entityInstance = null; 148 149 if(parameterCount == 1) { 150 if(entityRef != null) { 151 entityInstance = getEntityInstanceByEntityRef(eea, entityRef); 152 } else if(uuid != null) { 153 entityInstance = getEntityInstanceByUuid(eea, uuid); 154 } 155 } else { 156 handleExecutionError(InvalidParameterCountException.class, eea, ExecutionErrors.InvalidParameterCount.name()); 157 } 158 159 if((eea == null || !eea.hasExecutionErrors()) && componentVendorName != null && entityTypeNames.length > 0) { 160 var entityTypeDetail = entityInstance.getEntityType().getLastDetail(); 161 var foundComponentVendorName = entityTypeDetail.getComponentVendor().getLastDetail().getComponentVendorName(); 162 var foundEntityTypeName = entityTypeDetail.getEntityTypeName(); 163 var found = false; 164 165 if(foundComponentVendorName.equals(componentVendorName)) { 166 for(var entityTypeName : entityTypeNames) { 167 if(entityTypeName.equals(foundEntityTypeName)) { 168 found = true; 169 break; 170 } 171 } 172 } 173 174 if(!found) { 175 handleExecutionError(InvalidEntityTypeException.class, eea, ExecutionErrors.InvalidEntityType.name(), foundComponentVendorName, foundEntityTypeName); 176 entityInstance = null; 177 } 178 } 179 180 return entityInstance; 181 } 182 183 public EntityInstance getEntityInstance(final ExecutionErrorAccumulator eea, final EntityRefSpec entityRefSpec, 184 final UuidSpec uuidSpec, final String componentVendorName, final String... entityTypeNames) { 185 return getEntityInstance(eea, entityRefSpec.getEntityRef(), uuidSpec.getUuid(), 186 componentVendorName, entityTypeNames); 187 } 188 189 public EntityInstance getEntityInstance(final ExecutionErrorAccumulator eea, final UniversalEntitySpec universalEntitySpec) { 190 return getEntityInstance(eea, universalEntitySpec.getEntityRef(), 191 universalEntitySpec.getUuid(), null); 192 } 193 194 public EntityInstance getEntityInstance(final ExecutionErrorAccumulator eea, final UniversalEntitySpec universalEntitySpec, 195 final String componentVendorName, final String... entityTypeNames) { 196 return getEntityInstance(eea, universalEntitySpec.getEntityRef(), 197 universalEntitySpec.getUuid(), componentVendorName, entityTypeNames); 198 } 199 200 public int countPossibleEntitySpecs(final String entityRef, final String uuid) { 201 return (entityRef == null ? 0 : 1) + (uuid == null ? 0 : 1); 202 } 203 204 public int countPossibleEntitySpecs(final EntityRefSpec entityRefSpec, final UuidSpec uuidSpec) { 205 return countPossibleEntitySpecs(entityRefSpec == null ? null : entityRefSpec.getEntityRef(), 206 uuidSpec == null ? null : uuidSpec.getUuid()); 207 } 208 209 public int countPossibleEntitySpecs(final UniversalEntitySpec universalEntitySpec) { 210 return universalEntitySpec == null ? 0 : countPossibleEntitySpecs(universalEntitySpec.getEntityRef(), 211 universalEntitySpec.getUuid()); 212 } 213 214 public String getEntityRefFromEntityInstance(EntityInstance entityInstance) { 215 var entityTypeDetail = entityInstance.getEntityType().getLastDetail(); 216 var componentVendorDetail = entityTypeDetail.getComponentVendor().getLastDetail(); 217 218 return componentVendorDetail.getComponentVendorName() + '.' + 219 entityTypeDetail.getEntityTypeName() + '.' + 220 entityInstance.getEntityUniqueId(); 221 } 222 223 public void deleteEntityInstance(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance, final BasePK deletedBy) { 224 var componentVendorName = entityInstance.getEntityType().getLastDetail().getComponentVendor().getLastDetail().getComponentVendorName(); 225 226 if(!ComponentVendors.ECHO_THREE.name().equals(componentVendorName)) { 227 entityInstanceControl.deleteEntityInstance(entityInstance, deletedBy); 228 } else { 229 handleExecutionError(InvalidComponentVendorException.class, eea, ExecutionErrors.InvalidComponentVendor.name(), componentVendorName); 230 } 231 } 232 233 public void removeEntityInstance(final ExecutionErrorAccumulator eea, final EntityInstance entityInstance) { 234 var componentVendorName = entityInstance.getEntityType().getLastDetail().getComponentVendor().getLastDetail().getComponentVendorName(); 235 236 if(!ComponentVendors.ECHO_THREE.name().equals(componentVendorName)) { 237 entityInstanceControl.removeEntityInstance(entityInstance); 238 } else { 239 handleExecutionError(InvalidComponentVendorException.class, eea, ExecutionErrors.InvalidComponentVendor.name(), componentVendorName); 240 } 241 } 242 243}