Fix WCM-857

Added AVMLockingService.removeLocksInDirectory() which, given the state of AttributeService, is a bit
of a sledgehammer.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6932 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2007-10-08 15:14:11 +00:00
parent e5bef04dbf
commit 2a47726733
3 changed files with 113 additions and 103 deletions

View File

@@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@@ -61,13 +61,13 @@ import org.springframework.context.ApplicationContextAware;
public class AVMLockingAwareService implements AVMService, ApplicationContextAware public class AVMLockingAwareService implements AVMService, ApplicationContextAware
{ {
private AVMService fService; private AVMService fService;
private AVMLockingService fLockingService; private AVMLockingService fLockingService;
private AuthenticationService fAuthenticationService; private AuthenticationService fAuthenticationService;
private ApplicationContext fContext; private ApplicationContext fContext;
public AVMLockingAwareService() public AVMLockingAwareService()
{ {
} }
@@ -79,7 +79,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
{ {
fContext = applicationContext; fContext = applicationContext;
} }
public void init() public void init()
{ {
fService = (AVMService)fContext.getBean("avmService"); fService = (AVMService)fContext.getBean("avmService");
@@ -678,6 +678,8 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
fService.removeNode(parent, name); fService.removeNode(parent, name);
String[] storePath = parent.split(":"); String[] storePath = parent.split(":");
fService.createSnapshot(storePath[0], null, null); fService.createSnapshot(storePath[0], null, null);
fLockingService.removeLocksInDirectory(getWebProject(storePath[0]), storePath[0],
storePath[1] + '/' + name);
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -689,6 +691,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
fService.removeNode(path); fService.removeNode(path);
String[] storePath = path.split(":"); String[] storePath = path.split(":");
fService.createSnapshot(storePath[0], null, null); fService.createSnapshot(storePath[0], null, null);
fLockingService.removeLocksInDirectory(getWebProject(storePath[0]), storePath[0], storePath[1]);
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -834,7 +837,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
grabLock(dirPath + '/' + name); grabLock(dirPath + '/' + name);
fService.uncover(dirPath, name); fService.uncover(dirPath, name);
} }
private String[] splitPath(String path) private String[] splitPath(String path)
{ {
String[] storePath = path.split(":"); String[] storePath = path.split(":");
@@ -844,7 +847,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
} }
return storePath; return storePath;
} }
private String getWebProject(String name) private String getWebProject(String name)
{ {
Map<QName, PropertyValue> results = fService.queryStorePropertyKey(name, QName.createQName(null, ".dns%")); Map<QName, PropertyValue> results = fService.queryStorePropertyKey(name, QName.createQName(null, ".dns%"));
@@ -855,7 +858,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa
String dnsString = results.keySet().iterator().next().getLocalName(); String dnsString = results.keySet().iterator().next().getLocalName();
return dnsString.substring(dnsString.lastIndexOf('.') + 1, dnsString.length()); return dnsString.substring(dnsString.lastIndexOf('.') + 1, dnsString.length());
} }
private void grabLock(String path) private void grabLock(String path)
{ {
AVMNodeDescriptor desc = fService.lookup(-1, path, false); AVMNodeDescriptor desc = fService.lookup(-1, path, false);

View File

@@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@@ -66,31 +66,31 @@ public class AVMLockingServiceImpl implements AVMLockingService
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"; public static final String STORES = "stores";
private static final String ROLE_CONTENT_MANAGER = "ContentManager"; private static final String ROLE_CONTENT_MANAGER = "ContentManager";
private static final Log logger = LogFactory.getLog(AVMLockingServiceImpl.class); private static final Log logger = LogFactory.getLog(AVMLockingServiceImpl.class);
/** /**
* Store name containing the web project nodes. * Store name containing the web project nodes.
*/ */
private String webProjectStore; private String webProjectStore;
/** /**
* SearchService for access to web project properties. * SearchService for access to web project properties.
*/ */
private SearchService fSearchService; private SearchService fSearchService;
/** /**
* AttributeService reference. * AttributeService reference.
*/ */
private AttributeService fAttributeService; private AttributeService fAttributeService;
/** /**
* AuthorityService reference. * AuthorityService reference.
*/ */
private AuthorityService fAuthorityService; private AuthorityService fAuthorityService;
/** /**
* PersonService reference. * PersonService reference.
*/ */
@@ -100,13 +100,13 @@ public class AVMLockingServiceImpl implements AVMLockingService
* The NodeService. * The NodeService.
*/ */
private NodeService fNodeService; private NodeService fNodeService;
/** /**
* Transaction Helper reference. * Transaction Helper reference.
*/ */
private RetryingTransactionHelper fRetryingTransactionHelper; private RetryingTransactionHelper fRetryingTransactionHelper;
/** /**
* @param webProjectStore The webProjectStore to set * @param webProjectStore The webProjectStore to set
*/ */
@@ -132,7 +132,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
fAuthorityService = service; fAuthorityService = service;
} }
/** /**
* Set the person service reference. * Set the person service reference.
* @param service * @param service
@@ -141,7 +141,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
fPersonService = service; fPersonService = service;
} }
/** /**
* Setter for RetryingTransactionHelper reference. * Setter for RetryingTransactionHelper reference.
* @param helper * @param helper
@@ -150,7 +150,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
fRetryingTransactionHelper = helper; fRetryingTransactionHelper = helper;
} }
public void setSearchService(SearchService service) public void setSearchService(SearchService service)
{ {
fSearchService = service; fSearchService = service;
@@ -160,10 +160,10 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
fNodeService = service; fNodeService = service;
} }
public void init() public void init()
{ {
RetryingTransactionHelper.RetryingTransactionCallback<Object> callback = RetryingTransactionHelper.RetryingTransactionCallback<Object> callback =
new RetryingTransactionHelper.RetryingTransactionCallback<Object>() new RetryingTransactionHelper.RetryingTransactionCallback<Object>()
{ {
public Object execute() public Object execute()
@@ -181,7 +181,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
}; };
fRetryingTransactionHelper.doInTransaction(callback, false); fRetryingTransactionHelper.doInTransaction(callback, false);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#getLock(java.lang.String, java.lang.String) * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#getLock(java.lang.String, java.lang.String)
*/ */
@@ -192,7 +192,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
keys.add(LOCK_TABLE); keys.add(LOCK_TABLE);
keys.add(WEB_PROJECTS); keys.add(WEB_PROJECTS);
keys.add(webProject); keys.add(webProject);
List<Pair<String, Attribute>> attrs = List<Pair<String, Attribute>> attrs =
fAttributeService.query(keys, new AttrQueryEquals(MD5.Digest(path.getBytes()))); fAttributeService.query(keys, new AttrQueryEquals(MD5.Digest(path.getBytes())));
if (attrs.size() == 0) if (attrs.size() == 0)
{ {
@@ -218,7 +218,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
} }
return path.replaceAll("/+", "/"); return path.replaceAll("/+", "/");
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.service.cmr.avm.locking.AVMLockingService#getUsersLocks(java.lang.String) * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#getUsersLocks(java.lang.String)
*/ */
@@ -272,7 +272,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
fAttributeService.setAttribute(keys, digest, lockData); fAttributeService.setAttribute(keys, digest, lockData);
// Attribute reverseEntry = new MapAttributeValue(); // Attribute reverseEntry = new MapAttributeValue();
// reverseEntry.put("web_project", new StringAttributeValue(lock.getWebProject())); // reverseEntry.put("web_project", new StringAttributeValue(lock.getWebProject()));
// reverseEntry.put("path", new StringAttributeValue(lock.getPath())); // 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);
@@ -322,42 +322,41 @@ public class AVMLockingServiceImpl implements AVMLockingService
} }
keys.remove(3); keys.remove(3);
fAttributeService.removeAttribute(keys, pathKey); fAttributeService.removeAttribute(keys, pathKey);
// AVMLock lock = new AVMLock(lockData); }
// List<String> userKeys = new ArrayList<String>();
// userKeys.add(LOCK_TABLE); /* (non-Javadoc)
// userKeys.add(USERS); * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#removeLocksInDirectory(java.lang.String, java.lang.String, java.lang.String)
// for (String user : lock.getOwners()) */
// { public void removeLocksInDirectory(String webProject, String store,
// userKeys.add(user); String path)
// Attribute userLocks = fAttributeService.getAttribute(userKeys); {
// for (int i = userLocks.size() - 1; i >= 0; i--) path = normalizePath(path);
// { if (logger.isDebugEnabled())
// Attribute lockInfo = userLocks.get(i); {
// if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject()) logger.debug("removing locks in directory: " + path + "(" + webProject + ", " + store + ")");
// && lockInfo.get("path").getStringValue().equals(lock.getPath())) }
// { List<String> keys = new ArrayList<String>();
// fAttributeService.removeAttribute(userKeys, i); keys.add(LOCK_TABLE);
// break; keys.add(WEB_PROJECTS);
// } keys.add(webProject);
// } Attribute map = fAttributeService.getAttribute(keys);
// userKeys.remove(2); if (map == null)
// } {
// List<String> storeKeys = new ArrayList<String>(3); return;
// storeKeys.add(LOCK_TABLE); }
// storeKeys.add(STORES); for (Map.Entry<String, Attribute> entry : map.entrySet())
// String store = lock.getStore(); {
// storeKeys.add(store); if (logger.isDebugEnabled())
// Attribute storeLocks = fAttributeService.getAttribute(storeKeys); {
// for (int i = storeLocks.size() - 1; i >= 0; i--) logger.debug(entry);
// { }
// Attribute lockInfo = storeLocks.get(i); Attribute child = entry.getValue();
// if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject()) && if (child.get("store").getStringValue().equals(store) &&
// lockInfo.get("path").getStringValue().equals(lock.getPath())) child.get("path").getStringValue().startsWith(path + '/'))
// { {
// fAttributeService.removeAttribute(storeKeys, i); fAttributeService.removeAttribute(keys, entry.getKey());
// break; }
// } }
// }
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -395,7 +394,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
result.add(new AVMLock(lockData)); result.add(new AVMLock(lockData));
} }
} }
return result; return result;
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -535,7 +534,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
int index = store.indexOf("--"); int index = store.indexOf("--");
if (index >= 0) if (index >= 0)
{ {
webProject = store.substring(0, index); webProject = store.substring(0, index);
} }
List<String> keys = new ArrayList<String>(3); List<String> keys = new ArrayList<String>(3);
keys.add(LOCK_TABLE); keys.add(LOCK_TABLE);
@@ -557,7 +556,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
} }
for (String name : toDelete) for (String name : toDelete)
{ {
fAttributeService.removeAttribute(keys, name); fAttributeService.removeAttribute(keys, name);
} }
} }
@@ -612,10 +611,10 @@ public class AVMLockingServiceImpl implements AVMLockingService
{ {
throw new AVMBadArgumentException("Malformed AVM Path : " + avmPath); throw new AVMBadArgumentException("Malformed AVM Path : " + avmPath);
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Testing lock access on path: " + avmPath + " for user: " + user + " in webproject: " + webProject); logger.debug("Testing lock access on path: " + avmPath + " for user: " + user + " in webproject: " + webProject);
// check if a lock exists at all for this path in the specified webproject id // check if a lock exists at all for this path in the specified webproject id
String path = normalizePath(storePath[1]); String path = normalizePath(storePath[1]);
AVMLock lock = getLock(webProject, path); AVMLock lock = getLock(webProject, path);
@@ -625,7 +624,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
logger.debug(" GRANTED: No lock found."); logger.debug(" GRANTED: No lock found.");
return true; return true;
} }
// locks are ignored in a workflow store // locks are ignored in a workflow store
if (storePath[0].contains("--workflow")) if (storePath[0].contains("--workflow"))
{ {
@@ -633,7 +632,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
logger.debug(" GRANTED: Workflow store path."); logger.debug(" GRANTED: Workflow store path.");
return true; return true;
} }
// locks are specific to a store - no access if the stores are different // locks are specific to a store - no access if the stores are different
if (!lock.getStore().equals(storePath[0])) if (!lock.getStore().equals(storePath[0]))
{ {
@@ -641,7 +640,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
logger.debug(" DENIED: Store on path and lock (" + lock.getStore().toString() + ") do not match."); logger.debug(" DENIED: Store on path and lock (" + lock.getStore().toString() + ") do not match.");
return false; return false;
} }
// check for content manager role - we allow access to all managers within the same store // check for content manager role - we allow access to all managers within the same store
List<ChildAssociationRef> children = fNodeService.getChildAssocs( List<ChildAssociationRef> children = fNodeService.getChildAssocs(
webProjectRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); webProjectRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL);
@@ -656,7 +655,7 @@ public class AVMLockingServiceImpl implements AVMLockingService
return true; return true;
} }
} }
// finally check the owners of the lock against the specified authority // finally check the owners of the lock against the specified authority
List<String> owners = lock.getOwners(); List<String> owners = lock.getOwners();
for (String owner : owners) for (String owner : owners)
@@ -674,12 +673,12 @@ public class AVMLockingServiceImpl implements AVMLockingService
return true; return true;
} }
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug(" DENIED: User did not match as lock owner."); logger.debug(" DENIED: User did not match as lock owner.");
return false; return false;
} }
/** /**
* Helper function that checks the transitive closure of authorities for user. * Helper function that checks the transitive closure of authorities for user.
* @param user * @param user

View File

@@ -15,11 +15,11 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of * As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing * FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing * http://www.alfresco.com/legal/licensing
*/ */
@@ -40,15 +40,15 @@ public interface AVMLockingService
{ {
DISCRETIONARY DISCRETIONARY
}; };
/** /**
* Creates a lock of the given type on a path. * Creates a lock of the given type on a path.
* The lock is used to control access to all the * The lock is used to control access to all the
* corresponding paths in the given path's web project. * corresponding paths in the given path's web project.
* @param lock The lock structure to create. * @param lock The lock structure to create.
*/ */
public void lockPath(AVMLock lock); public void lockPath(AVMLock lock);
/** /**
* Get a lock on a given path * Get a lock on a given path
* @param webProject The website for which to get the lock. * @param webProject The website for which to get the lock.
@@ -56,7 +56,7 @@ public interface AVMLockingService
* @return The Lock structure or null if there is no lock. * @return The Lock structure or null if there is no lock.
*/ */
public AVMLock getLock(String webProject, String path); public AVMLock getLock(String webProject, String path);
/** /**
* Modify a lock. Null change parameters are ignored. * Modify a lock. Null change parameters are ignored.
* @param webProject The name of the web project. * @param webProject The name of the web project.
@@ -69,53 +69,61 @@ public interface AVMLockingService
public void modifyLock(String webProject, String path, String newPath, public void modifyLock(String webProject, String path, String newPath,
String newStore, List<String> usersToRemove, String newStore, List<String> usersToRemove,
List<String> usersToAdd); 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.
* @param path The store relative path of the lock. * @param path The store relative path of the lock.
*/ */
public void removeLock(String webProject, String path); public void removeLock(String webProject, String path);
/**
* Remove all locks on files contained within a directory.
* @param webProject
* @param store
* @param path
*/
public void removeLocksInDirectory(String webProject, String store, String path);
/** /**
* Removes all locks residing in a store. * Removes all locks residing in a store.
* @param store The store name. * @param store The store name.
*/ */
public void removeStoreLocks(String store); 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.
* @return The (possibly empty list) of the user's locks. * @return The (possibly empty list) of the user's locks.
*/ */
public List<AVMLock> getUsersLocks(String user); public List<AVMLock> getUsersLocks(String user);
/** /**
* Add a web project to the locking tables if it doesn't already exist. * Add a web project to the locking tables if it doesn't already exist.
* @param webProject The web project name. * @param webProject The web project name.
*/ */
public void addWebProject(String webProject); public void addWebProject(String webProject);
/** /**
* Remove a web project and all associated data from the locking tables. * Remove a web project and all associated data from the locking tables.
* @param webProject The web project name. * @param webProject The web project name.
*/ */
public void removeWebProject(String webProject); public void removeWebProject(String webProject);
/** /**
* Get all locks in a give web project. * Get all locks in a give web project.
* @param webProject The web project name. * @param webProject The web project name.
* @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. * Get all locks that reside in a given store.
* @param store The store name. * @param store The store name.
* @return All the locks found. * @return All the locks found.
*/ */
public List<AVMLock> getStoreLocks(String store); public List<AVMLock> getStoreLocks(String store);
/** /**
* Is the user allowed to do anything to the given asset, other than read? * 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 webProject The name of the web project that this path is being checked in.
@@ -124,7 +132,7 @@ public interface AVMLockingService
* @return Whether the user has access. * @return Whether the user has access.
*/ */
public boolean hasAccess(String webProject, String avmPath, String user); public boolean hasAccess(String webProject, String avmPath, String user);
/** /**
* Is the user allowed to do anything to the given asset, other than read? * Is the user allowed to do anything to the given asset, other than read?
* @param webProjectRef The NodeRef to the web project that this path is being checked in. * @param webProjectRef The NodeRef to the web project that this path is being checked in.
@@ -133,7 +141,7 @@ public interface AVMLockingService
* @return Whether the user has access. * @return Whether the user has access.
*/ */
public boolean hasAccess(NodeRef webProjectRef, String avmPath, String user); public boolean hasAccess(NodeRef webProjectRef, String avmPath, String user);
/** /**
* Get the names of all the web projects the service knows about. * Get the names of all the web projects the service knows about.
* @return The list of web project names. * @return The list of web project names.