Additions to the AVMLockingService API. All but one are implemented. None are tested.

Oh AVMLockingServiceTest will fail if not started from a clean database.  I'll fix that up 
in a bit.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5845 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2007-06-05 01:02:03 +00:00
parent f1347f3bf6
commit cd1aa771b4
3 changed files with 234 additions and 8 deletions

View File

@@ -34,9 +34,9 @@ import org.alfresco.repo.attributes.ListAttributeValue;
import org.alfresco.repo.attributes.MapAttributeValue; import org.alfresco.repo.attributes.MapAttributeValue;
import org.alfresco.repo.attributes.StringAttributeValue; import org.alfresco.repo.attributes.StringAttributeValue;
import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.attributes.AttrQueryEquals; import org.alfresco.service.cmr.attributes.AttrQueryEquals;
import org.alfresco.service.cmr.attributes.AttributeService; import org.alfresco.service.cmr.attributes.AttributeService;
import org.alfresco.service.cmr.avm.AVMBadArgumentException;
import org.alfresco.service.cmr.avm.AVMExistsException; import org.alfresco.service.cmr.avm.AVMExistsException;
import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.avm.locking.AVMLock; import org.alfresco.service.cmr.avm.locking.AVMLock;
@@ -53,6 +53,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
public static final String LOCK_TABLE = ".avm_lock_table"; public static final String LOCK_TABLE = ".avm_lock_table";
public static final String WEB_PROJECTS = "web_projects"; public static final String WEB_PROJECTS = "web_projects";
public static final String USERS = "users"; public static final String USERS = "users";
public static final String STORES = "stores";
/** /**
* AttributeService reference. * AttributeService reference.
@@ -88,7 +89,8 @@ public class AVMLockingServiceImpl implements AVMLockingService
public void init() public void init()
{ {
RetryingTransactionCallback callback = new RetryingTransactionCallback() RetryingTransactionHelper.RetryingTransactionCallback<Object> callback =
new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{ {
public Object execute() public Object execute()
{ {
@@ -100,6 +102,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
fAttributeService.setAttribute("", LOCK_TABLE, new MapAttributeValue()); fAttributeService.setAttribute("", LOCK_TABLE, new MapAttributeValue());
fAttributeService.setAttribute(LOCK_TABLE, WEB_PROJECTS, new MapAttributeValue()); fAttributeService.setAttribute(LOCK_TABLE, WEB_PROJECTS, new MapAttributeValue());
fAttributeService.setAttribute(LOCK_TABLE, USERS, new MapAttributeValue()); fAttributeService.setAttribute(LOCK_TABLE, USERS, new MapAttributeValue());
fAttributeService.setAttribute(LOCK_TABLE, STORES, new MapAttributeValue());
return null; return null;
} }
}; };
@@ -182,6 +185,9 @@ public class AVMLockingServiceImpl implements AVMLockingService
throw new AVMExistsException("Lock Exists: " + keys); throw new AVMExistsException("Lock Exists: " + keys);
} }
fAttributeService.setAttribute(keys, MD5.Digest(lock.getPath().getBytes()), lockData); fAttributeService.setAttribute(keys, MD5.Digest(lock.getPath().getBytes()), lockData);
Attribute reverseEntry = new MapAttributeValue();
reverseEntry.put("web_project", new StringAttributeValue(lock.getWebProject()));
reverseEntry.put("path", new StringAttributeValue(lock.getPath()));
keys.clear(); keys.clear();
keys.add(LOCK_TABLE); keys.add(LOCK_TABLE);
keys.add(USERS); keys.add(USERS);
@@ -195,12 +201,22 @@ public class AVMLockingServiceImpl implements AVMLockingService
fAttributeService.setAttribute(keys, user, new ListAttributeValue()); fAttributeService.setAttribute(keys, user, new ListAttributeValue());
} }
keys.add(user); keys.add(user);
Attribute entry = new MapAttributeValue(); fAttributeService.addAttribute(keys, reverseEntry);
entry.put("web_project", new StringAttributeValue(lock.getWebProject()));
entry.put("path", new StringAttributeValue(lock.getPath()));
fAttributeService.addAttribute(keys, entry);
keys.remove(2); keys.remove(2);
} }
String store = lock.getStore();
keys.clear();
keys.add(LOCK_TABLE);
keys.add(STORES);
keys.add(store);
Attribute storeEntry = fAttributeService.getAttribute(keys);
keys.remove(2);
if (storeEntry == null)
{
fAttributeService.setAttribute(keys, store, new ListAttributeValue());
}
keys.add(store);
fAttributeService.addAttribute(keys, reverseEntry);
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -230,7 +246,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
userKeys.add(user); userKeys.add(user);
Attribute userLocks = fAttributeService.getAttribute(userKeys); Attribute userLocks = fAttributeService.getAttribute(userKeys);
for (int i = 0; i < userLocks.size(); i++) for (int i = userLocks.size() - 1; i >= 0; i--)
{ {
Attribute lockInfo = userLocks.get(i); Attribute lockInfo = userLocks.get(i);
if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject()) if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject())
@@ -242,6 +258,22 @@ public class AVMLockingServiceImpl implements AVMLockingService
} }
userKeys.remove(2); userKeys.remove(2);
} }
List<String> storeKeys = new ArrayList<String>();
storeKeys.add(LOCK_TABLE);
storeKeys.add(STORES);
String store = lock.getStore();
storeKeys.add(store);
Attribute storeLocks = fAttributeService.getAttribute(storeKeys);
for (int i = storeLocks.size() - 1; i >= 0; i--)
{
Attribute lockInfo = storeLocks.get(i);
if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject()) &&
lockInfo.get("path").getStringValue().equals(lock.getPath()))
{
fAttributeService.removeAttribute(storeKeys, i);
break;
}
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -291,6 +323,8 @@ public class AVMLockingServiceImpl implements AVMLockingService
userKeys.add(LOCK_TABLE); userKeys.add(LOCK_TABLE);
userKeys.add(USERS); userKeys.add(USERS);
List<String> users = fAttributeService.getKeys(userKeys); List<String> users = fAttributeService.getKeys(userKeys);
// TODO This works incredibly slowly. AttributeService has to support
// extended querying on values.
for (String user : users) for (String user : users)
{ {
userKeys.add(user); userKeys.add(user);
@@ -307,9 +341,149 @@ public class AVMLockingServiceImpl implements AVMLockingService
userKeys.remove(2); userKeys.remove(2);
fAttributeService.setAttribute(userKeys, user, userLocks); fAttributeService.setAttribute(userKeys, user, userLocks);
} }
List<String> storeKeys = new ArrayList<String>();
storeKeys.add(LOCK_TABLE);
storeKeys.add(STORES);
List<String> stores = fAttributeService.getKeys(storeKeys);
// TODO Ditto.
for (String store : stores)
{
storeKeys.add(store);
Attribute storeLocks = fAttributeService.getAttribute(storeKeys);
Iterator<Attribute> iter = storeLocks.iterator();
while (iter.hasNext())
{
Attribute lockInfo = iter.next();
if (lockInfo.get("web_project").getStringValue().equals(webProject))
{
iter.remove();
}
}
storeKeys.remove(2);
fAttributeService.setAttribute(storeKeys, store, storeLocks);
}
List<String> keys = new ArrayList<String>(); List<String> keys = new ArrayList<String>();
keys.add(LOCK_TABLE); keys.add(LOCK_TABLE);
keys.add(WEB_PROJECTS); keys.add(WEB_PROJECTS);
fAttributeService.removeAttribute(keys, webProject); fAttributeService.removeAttribute(keys, webProject);
} }
/* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#getStoreLocks(java.lang.String)
*/
public List<AVMLock> getStoreLocks(String store)
{
List<AVMLock> locks = new ArrayList<AVMLock>();
List<String> keys = new ArrayList<String>();
keys.add(LOCK_TABLE);
keys.add(STORES);
keys.add(store);
List<String> lockKeys = new ArrayList<String>();
lockKeys.add(LOCK_TABLE);
lockKeys.add(WEB_PROJECTS);
Attribute storeLocks = fAttributeService.getAttribute(keys);
for (Attribute lockInfo : storeLocks)
{
String webProject = lockInfo.get("web_project").getStringValue();
String path = lockInfo.get("path").getStringValue();
lockKeys.add(webProject);
lockKeys.add(MD5.Digest(path.getBytes()));
Attribute lockData = fAttributeService.getAttribute(lockKeys);
locks.add(new AVMLock(lockData));
lockKeys.remove(3);
lockKeys.remove(2);
}
return locks;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#modifyLock(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.util.List, java.util.List)
*/
public void modifyLock(String webProject, String path, String newPath, String newStore, List<String> usersToRemove, List<String> usersToAdd)
{
AVMLock lock = getLock(webProject, path);
if (lock == null)
{
throw new AVMNotFoundException("Lock not found for " + webProject + ":" + path);
}
removeLock(webProject, path);
if (newPath != null)
{
lock.setPath(newPath);
}
if (newStore != null)
{
lock.setStore(newStore);
}
if (usersToRemove != null)
{
for (String user : usersToRemove)
{
lock.getOwners().remove(user);
}
}
if (usersToAdd != null)
{
for (String user : usersToAdd)
{
if (lock.getOwners().contains(user))
{
continue;
}
lock.getOwners().add(user);
}
}
lockPath(lock);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#removeStoreLocks(java.lang.String)
*/
public void removeStoreLocks(String store)
{
List<String> storeKeys = new ArrayList<String>();
storeKeys.add(LOCK_TABLE);
storeKeys.add(STORES);
storeKeys.add(store);
Attribute storeLocks = fAttributeService.getAttribute(storeKeys);
if (storeLocks == null)
{
return;
}
for (Attribute lockInfo : storeLocks)
{
removeLock(lockInfo.get("web_project").getStringValue(),
lockInfo.get("path").getStringValue());
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#motherMayI(java.lang.String, java.lang.String)
*/
public boolean motherMayI(String webProject, String avmPath, String user)
{
String[] storePath = avmPath.split(":");
if (storePath.length != 2)
{
throw new AVMBadArgumentException("Malformed AVM Path : " + avmPath);
}
AVMLock lock = getLock(webProject, storePath[1]);
if (lock == null)
{
return true;
}
if (!lock.getStore().equals(storePath[0]))
{
return false;
}
List<String> owners = lock.getOwners();
if (owners.contains(user))
{
return true;
}
// TODO Figure out how the users, groups, roles mess works and give an answer
// based on that. <rant>Our entire access control and user, group, role approach
// is apalling and needs to be replaced.</rant>
return false;
}
} }

View File

@@ -97,7 +97,6 @@ public class AVMLock implements Serializable
fOwners = owners; fOwners = owners;
} }
public AVMLock(Attribute lockData) public AVMLock(Attribute lockData)
{ {
fPath = lockData.get(PATH).getStringValue(); fPath = lockData.get(PATH).getStringValue();
@@ -143,6 +142,15 @@ public class AVMLock implements Serializable
return fPath; return fPath;
} }
/**
* Set the path of this lock.
* @param path
*/
public void setPath(String path)
{
fPath = path;
}
/** /**
* @return the Store * @return the Store
*/ */
@@ -151,6 +159,15 @@ public class AVMLock implements Serializable
return fStore; return fStore;
} }
/**
* Set the store of this lock.
* @param store
*/
public void setStore(String store)
{
fStore = store;
}
/** /**
* @return the Type * @return the Type
*/ */

View File

@@ -55,6 +55,19 @@ public interface AVMLockingService
*/ */
public AVMLock getLock(String webProject, String path); public AVMLock getLock(String webProject, String path);
/**
* Modify a lock. Null change parameters are ignored.
* @param webProject The name of the web project.
* @param path The path of the lock.
* @param newPath The path that the lock should be given. (may be null)
* @param newStore The store that the lock should be given. (may be null)
* @param usersToRemove List of users to remove from the lock. (may be null)
* @param usersToAdd List of users to add to the lock. (may be null)
*/
public void modifyLock(String webProject, String path, String newPath,
String newStore, List<String> usersToRemove,
List<String> usersToAdd);
/** /**
* Remove a lock. * Remove a lock.
* @param webProject The web project the lock lives in. * @param webProject The web project the lock lives in.
@@ -62,6 +75,12 @@ public interface AVMLockingService
*/ */
public void removeLock(String webProject, String path); public void removeLock(String webProject, String path);
/**
* Removes all locks residing in a store.
* @param store The store name.
*/
public void removeStoreLocks(String store);
/** /**
* Get all the locks that a user owns. * Get all the locks that a user owns.
* @param user The name of the user. * @param user The name of the user.
@@ -87,4 +106,20 @@ public interface AVMLockingService
* @return All the locks found. * @return All the locks found.
*/ */
public List<AVMLock> getWebProjectLocks(String webProject); public List<AVMLock> getWebProjectLocks(String webProject);
/**
* Get all locks that reside in a given store.
* @param store The store name.
* @return All the locks found.
*/
public List<AVMLock> getStoreLocks(String store);
/**
* Is the user allowed to do anything to the given asset, other than read?
* @param webProject The name of the web project that this path is being checked in.
* @param avmPath A full avmPath
* @param user The name of the user, group, role to check on.
* @return Mother's verdict.
*/
public boolean motherMayI(String webProject, String avmPath, String user);
} }