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