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