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.transfer; 018 019import com.echothree.model.control.core.common.transfer.EntityLockTransfer; 020import com.echothree.model.control.core.server.CoreDebugFlags; 021import com.echothree.model.control.core.server.control.EntityInstanceControl; 022import com.echothree.model.data.core.common.pk.EntityInstancePK; 023import com.echothree.model.data.core.server.entity.EntityInstance; 024import com.echothree.model.data.core.server.factory.EntityInstanceFactory; 025import com.echothree.model.data.user.server.entity.UserVisit; 026import com.echothree.util.common.exception.EntityLockException; 027import com.echothree.util.common.persistence.BasePK; 028import com.echothree.util.server.persistence.DslContextFactory; 029import com.echothree.util.server.persistence.EntityPermission; 030import com.echothree.util.server.persistence.PersistenceUtils; 031import com.echothree.util.server.persistence.Session; 032import java.sql.SQLException; 033import javax.enterprise.context.RequestScoped; 034 035@RequestScoped 036public class EntityLockTransferCache 037 extends BaseCoreTransferCache { 038 039 EntityInstanceControl entityInstanceControl = Session.getModelController(EntityInstanceControl.class); 040 041 /** Creates a new instance of EntityLockTransferCache */ 042 protected EntityLockTransferCache() { 043 super(); 044 } 045 046 @SuppressWarnings("Finally") 047 public EntityLockTransfer getEntityLockTransfer(final UserVisit userVisit, BasePK lockTarget) { 048 var entityLockTransfer = (EntityLockTransfer)get(lockTarget); 049 050 if(entityLockTransfer == null) { 051 var lockTargetEntityInstance = entityInstanceControl.getEntityInstanceByBasePK(lockTarget); 052 053 entityLockTransfer = getEntityLockTransferByEntityInstance(userVisit, lockTargetEntityInstance, true); 054 } 055 056 return entityLockTransfer; 057 } 058 059 public EntityLockTransfer getEntityLockTransferByEntityInstance(final UserVisit userVisit, EntityInstance lockTargetEntityInstance) { 060 return getEntityLockTransferByEntityInstance(userVisit, lockTargetEntityInstance, false); 061 } 062 063 private EntityLockTransfer getEntityLockTransferByEntityInstance(final UserVisit userVisit, EntityInstance lockTargetEntityInstance, boolean putInCache) { 064 EntityLockTransfer entityLockTransfer = null; 065 066 try (var conn = DslContextFactory.getInstance().getNTDslContext().parsingConnection()) { 067 long lockTargetEntityInstanceId = lockTargetEntityInstance.getPrimaryKey().getEntityId(); 068 long lockedByEntityInstanceId = 0; 069 long lockedTime = 0; 070 long expirationTime = 0; 071 072 if(CoreDebugFlags.LogEntityLocks) { 073 getLog().info(">>> getEntityLockTransfer(lockTargetEntityInstance=" + lockTargetEntityInstance.getPrimaryKey() + ")"); 074 } 075 076 if(CoreDebugFlags.LogEntityLocks) { 077 getLog().info("--- lockTargetEntityInstance=" + lockTargetEntityInstance); 078 } 079 080 try (var ps = conn.prepareStatement( 081 "SELECT lcks_lockedbyentityinstanceid, lcks_lockedtime, lcks_lockexpirationtime " 082 + "FROM entitylocks " 083 + "WHERE lcks_locktargetentityinstanceid = ?")) { 084 ps.setLong(1, lockTargetEntityInstanceId); 085 086 try (var rs = ps.executeQuery()) { 087 if (rs.next()) { 088 lockedByEntityInstanceId = rs.getLong(1); 089 lockedTime = rs.getLong(2); 090 expirationTime = rs.getLong(3); 091 } 092 } catch (SQLException se) { 093 throw new EntityLockException(se); 094 } 095 } catch (SQLException se) { 096 throw new EntityLockException(se); 097 } 098 099 if(lockedByEntityInstanceId != 0) { 100 var lockedByEntityInstancePK = new EntityInstancePK(lockedByEntityInstanceId); 101 var lockedByEntityInstance = EntityInstanceFactory.getInstance().getEntityFromPK(EntityPermission.READ_ONLY, lockedByEntityInstancePK); 102 var lockTargetEntityInstanceTransfer = entityInstanceControl.getEntityInstanceTransfer(userVisit, lockTargetEntityInstance, false, false, false, false); 103 var lockedByEntityInstanceTransfer = entityInstanceControl.getEntityInstanceTransfer(userVisit, lockedByEntityInstance, false, false, false, false); 104 105 if(CoreDebugFlags.LogEntityLocks) { 106 getLog().info("--- lockedByEntityInstancePK = " + lockedByEntityInstancePK); 107 getLog().info("--- lockedByEntityInstance = " + lockedByEntityInstance); 108 getLog().info("--- lockTargetEntityInstanceTransfer = " + lockTargetEntityInstanceTransfer.getEntityRef()); 109 getLog().info("--- lockTargetEntityInstanceTransfer = " + lockTargetEntityInstanceTransfer.getEntityRef()); 110 } 111 112 var lockedTimeString = formatTypicalDateTime(userVisit, lockedTime); 113 var expirationTimeString = formatTypicalDateTime(userVisit, expirationTime); 114 115 entityLockTransfer = new EntityLockTransfer(lockTargetEntityInstanceTransfer, lockedByEntityInstanceTransfer, lockedTime, lockedTimeString, expirationTime, expirationTimeString); 116 } 117 118 if(putInCache) { 119 transferCache.put(PersistenceUtils.getInstance().getBasePKFromEntityInstance(lockTargetEntityInstance), entityLockTransfer); 120 } 121 } catch (SQLException se) { 122 throw new EntityLockException(se); 123 } 124 125 if(CoreDebugFlags.LogEntityLocks) { 126 getLog().info("<<< entityLockTransfer=" + entityLockTransfer); 127 } 128 129 return entityLockTransfer; 130 } 131 132}