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