/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* This software is protected by the OLAT software license.<br>
* Use is subject to license terms.<br>
* See LICENSE.TXT in this distribution for details.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.<br>
* All rights reserved.
* <p>
*/
package org.olat.util.locks;
import org.hibernate.Hibernate;
import org.hibernate.type.Type;
import org.olat.admin.user.delete.service.UserDeletionManager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.coordinate.LockEntry;
import org.olat.core.util.coordinate.LockResult;
import org.olat.core.util.coordinate.LockResultImpl;
import org.olat.core.util.coordinate.PersistentLockManager;
import org.olat.core.util.resource.OresHelper;
import org.olat.properties.Property;
import org.olat.properties.PropertyManager;
import org.olat.user.UserDataDeletable;
/**
* Description:<br>
* TODO: patrickb Class Description for DBPersistentLockManager
* <P>
* Initial Date: 21.06.2006 <br>
*
* @author patrickb
*/
public class DBPersistentLockManager implements PersistentLockManager,UserDataDeletable {
private static final String CATEGORY_PERSISTENTLOCK = "o_lock";
private DBPersistentLockManager() {
UserDeletionManager.getInstance().registerDeletableUserData(this);
}
/**
* @see org.olat.core.util.locks.PersistentLockManager#aquirePersistentLock(org.olat.core.id.OLATResourceable,
* org.olat.core.id.Identity, java.lang.String)
*/
public LockResult aquirePersistentLock(OLATResourceable ores, Identity ident, String locksubkey) {
//synchronisation is solved in the LockManager
LockResult lres;
PropertyManager pm = PropertyManager.getInstance();
String derivedLockString = OresHelper.createStringRepresenting(ores, locksubkey);
long aqTime;
Identity lockOwner;
boolean success;
Property p;
p = pm.findProperty(null, null, null, CATEGORY_PERSISTENTLOCK, derivedLockString);
if (p == null) {
// no persistent lock acquired yet
// save a property: cat = o_lock, key = derivedLockString, Longvalue = key
// of identity acquiring the lock
Property newp = pm.createPropertyInstance(null, null, null, CATEGORY_PERSISTENTLOCK, derivedLockString, null, ident.getKey(), null,
null);
pm.saveProperty(newp);
aqTime = System.currentTimeMillis();
lockOwner = ident;
success = true;
} else {
// already acquired, but check on reaquiring
aqTime = p.getLastModified().getTime();
Long lockOwnerKey = p.getLongValue();
if (ident.getKey().equals(lockOwnerKey)) {
// reaquire ok
success = true;
} else {
// already locked by an other person
success = false;
}
// FIXME:fj:c find a better way to retrieve information about the
// lock-holder
lockOwner = ManagerFactory.getManager().loadIdentityByKey(lockOwnerKey);
}
LockEntry le = new LockEntry(derivedLockString, aqTime, lockOwner);
lres = new LockResultImpl(success, le);
return lres;
}
/**
* @see org.olat.core.util.locks.PersistentLockManager#releasePersistentLock(org.olat.core.util.locks.LockEntry)
*/
public void releasePersistentLock(LockResult le) {
//synchronisation is solved in the LockManager
String derivedLockString = ((LockResultImpl)le).getLockEntry().getKey();
PropertyManager pm = PropertyManager.getInstance();
Property p = pm.findProperty(null, null, null, CATEGORY_PERSISTENTLOCK, derivedLockString);
if (p == null) throw new AssertException("could not release lock: no lock in db, " + derivedLockString);
Identity ident = le.getOwner();
Long ownerKey = p.getLongValue();
if (!ownerKey.equals(ident.getKey())) throw new AssertException("user " + ident.getName()
+ " cannot release lock belonging to user with key " + ownerKey + " on resourcestring " + derivedLockString);
pm.deleteProperty(p);
}
/**
* Delete all persisting-locks for certain identity.
* @see org.olat.user.UserDataDeletable#deleteUserData(org.olat.core.id.Identity)
*/
public void deleteUserData(Identity identity, String newDeletedUserName) {
String query = "from v in class org.olat.properties.Property where v.category = ? and v.longValue = ?";
DBFactory.getInstance().delete(query, new Object[] { CATEGORY_PERSISTENTLOCK, identity.getKey() },
new Type[] { Hibernate.STRING, Hibernate.LONG });
Tracing.logDebug("All db-persisting-locks deleted for identity=" + identity, this.getClass());
}
}