diff --git a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java index 615830089a..b78bb26103 100644 --- a/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java +++ b/source/java/org/alfresco/repo/avm/AVMLockingAwareService.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * 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 - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * 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 + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing */ @@ -61,13 +61,13 @@ import org.springframework.context.ApplicationContextAware; public class AVMLockingAwareService implements AVMService, ApplicationContextAware { private AVMService fService; - + private AVMLockingService fLockingService; - + private AuthenticationService fAuthenticationService; - + private ApplicationContext fContext; - + public AVMLockingAwareService() { } @@ -79,7 +79,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa { fContext = applicationContext; } - + public void init() { fService = (AVMService)fContext.getBean("avmService"); @@ -678,6 +678,8 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa fService.removeNode(parent, name); String[] storePath = parent.split(":"); fService.createSnapshot(storePath[0], null, null); + fLockingService.removeLocksInDirectory(getWebProject(storePath[0]), storePath[0], + storePath[1] + '/' + name); } /* (non-Javadoc) @@ -689,6 +691,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa fService.removeNode(path); String[] storePath = path.split(":"); fService.createSnapshot(storePath[0], null, null); + fLockingService.removeLocksInDirectory(getWebProject(storePath[0]), storePath[0], storePath[1]); } /* (non-Javadoc) @@ -834,7 +837,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa grabLock(dirPath + '/' + name); fService.uncover(dirPath, name); } - + private String[] splitPath(String path) { String[] storePath = path.split(":"); @@ -844,7 +847,7 @@ public class AVMLockingAwareService implements AVMService, ApplicationContextAwa } return storePath; } - + private String getWebProject(String name) { Map 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(); return dnsString.substring(dnsString.lastIndexOf('.') + 1, dnsString.length()); } - + private void grabLock(String path) { AVMNodeDescriptor desc = fService.lookup(-1, path, false); diff --git a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java index 2f4f91afbc..a4ae2bcc3c 100644 --- a/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java +++ b/source/java/org/alfresco/repo/avm/locking/AVMLockingServiceImpl.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * 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 - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * 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 + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * 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 USERS = "users"; public static final String STORES = "stores"; - + private static final String ROLE_CONTENT_MANAGER = "ContentManager"; - + private static final Log logger = LogFactory.getLog(AVMLockingServiceImpl.class); - + /** * Store name containing the web project nodes. */ private String webProjectStore; - + /** * SearchService for access to web project properties. */ private SearchService fSearchService; - + /** * AttributeService reference. */ private AttributeService fAttributeService; - + /** * AuthorityService reference. */ private AuthorityService fAuthorityService; - + /** * PersonService reference. */ @@ -100,13 +100,13 @@ public class AVMLockingServiceImpl implements AVMLockingService * The NodeService. */ private NodeService fNodeService; - + /** * Transaction Helper reference. */ private RetryingTransactionHelper fRetryingTransactionHelper; - - + + /** * @param webProjectStore The webProjectStore to set */ @@ -132,7 +132,7 @@ public class AVMLockingServiceImpl implements AVMLockingService { fAuthorityService = service; } - + /** * Set the person service reference. * @param service @@ -141,7 +141,7 @@ public class AVMLockingServiceImpl implements AVMLockingService { fPersonService = service; } - + /** * Setter for RetryingTransactionHelper reference. * @param helper @@ -150,7 +150,7 @@ public class AVMLockingServiceImpl implements AVMLockingService { fRetryingTransactionHelper = helper; } - + public void setSearchService(SearchService service) { fSearchService = service; @@ -160,10 +160,10 @@ public class AVMLockingServiceImpl implements AVMLockingService { fNodeService = service; } - + public void init() { - RetryingTransactionHelper.RetryingTransactionCallback callback = + RetryingTransactionHelper.RetryingTransactionCallback callback = new RetryingTransactionHelper.RetryingTransactionCallback() { public Object execute() @@ -181,7 +181,7 @@ public class AVMLockingServiceImpl implements AVMLockingService }; fRetryingTransactionHelper.doInTransaction(callback, false); } - + /* (non-Javadoc) * @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(WEB_PROJECTS); keys.add(webProject); - List> attrs = + List> attrs = fAttributeService.query(keys, new AttrQueryEquals(MD5.Digest(path.getBytes()))); if (attrs.size() == 0) { @@ -218,7 +218,7 @@ public class AVMLockingServiceImpl implements AVMLockingService } return path.replaceAll("/+", "/"); } - + /* (non-Javadoc) * @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); // Attribute reverseEntry = new MapAttributeValue(); // 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.add(LOCK_TABLE); // keys.add(USERS); @@ -322,42 +322,41 @@ public class AVMLockingServiceImpl implements AVMLockingService } keys.remove(3); fAttributeService.removeAttribute(keys, pathKey); -// AVMLock lock = new AVMLock(lockData); -// List userKeys = new ArrayList(); -// userKeys.add(LOCK_TABLE); -// userKeys.add(USERS); -// for (String user : lock.getOwners()) -// { -// userKeys.add(user); -// Attribute userLocks = fAttributeService.getAttribute(userKeys); -// for (int i = userLocks.size() - 1; i >= 0; i--) -// { -// Attribute lockInfo = userLocks.get(i); -// if (lockInfo.get("web_project").getStringValue().equals(lock.getWebProject()) -// && lockInfo.get("path").getStringValue().equals(lock.getPath())) -// { -// fAttributeService.removeAttribute(userKeys, i); -// break; -// } -// } -// userKeys.remove(2); -// } -// List storeKeys = new ArrayList(3); -// 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) + * @see org.alfresco.service.cmr.avm.locking.AVMLockingService#removeLocksInDirectory(java.lang.String, java.lang.String, java.lang.String) + */ + public void removeLocksInDirectory(String webProject, String store, + String path) + { + path = normalizePath(path); + if (logger.isDebugEnabled()) + { + logger.debug("removing locks in directory: " + path + "(" + webProject + ", " + store + ")"); + } + List keys = new ArrayList(); + keys.add(LOCK_TABLE); + keys.add(WEB_PROJECTS); + keys.add(webProject); + Attribute map = fAttributeService.getAttribute(keys); + if (map == null) + { + return; + } + for (Map.Entry entry : map.entrySet()) + { + if (logger.isDebugEnabled()) + { + logger.debug(entry); + } + Attribute child = entry.getValue(); + if (child.get("store").getStringValue().equals(store) && + child.get("path").getStringValue().startsWith(path + '/')) + { + fAttributeService.removeAttribute(keys, entry.getKey()); + } + } } /* (non-Javadoc) @@ -395,7 +394,7 @@ public class AVMLockingServiceImpl implements AVMLockingService result.add(new AVMLock(lockData)); } } - return result; + return result; } /* (non-Javadoc) @@ -535,7 +534,7 @@ public class AVMLockingServiceImpl implements AVMLockingService int index = store.indexOf("--"); if (index >= 0) { - webProject = store.substring(0, index); + webProject = store.substring(0, index); } List keys = new ArrayList(3); keys.add(LOCK_TABLE); @@ -557,7 +556,7 @@ public class AVMLockingServiceImpl implements AVMLockingService } 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); } - + if (logger.isDebugEnabled()) 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 String path = normalizePath(storePath[1]); AVMLock lock = getLock(webProject, path); @@ -625,7 +624,7 @@ public class AVMLockingServiceImpl implements AVMLockingService logger.debug(" GRANTED: No lock found."); return true; } - + // locks are ignored in a workflow store if (storePath[0].contains("--workflow")) { @@ -633,7 +632,7 @@ public class AVMLockingServiceImpl implements AVMLockingService logger.debug(" GRANTED: Workflow store path."); return true; } - + // locks are specific to a store - no access if the stores are different 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."); return false; } - + // check for content manager role - we allow access to all managers within the same store List children = fNodeService.getChildAssocs( webProjectRef, WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); @@ -656,7 +655,7 @@ public class AVMLockingServiceImpl implements AVMLockingService return true; } } - + // finally check the owners of the lock against the specified authority List owners = lock.getOwners(); for (String owner : owners) @@ -674,12 +673,12 @@ public class AVMLockingServiceImpl implements AVMLockingService return true; } } - + if (logger.isDebugEnabled()) logger.debug(" DENIED: User did not match as lock owner."); return false; } - + /** * Helper function that checks the transitive closure of authorities for user. * @param user diff --git a/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java b/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java index 0adaee9339..b1e1af967c 100644 --- a/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java +++ b/source/java/org/alfresco/service/cmr/avm/locking/AVMLockingService.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * 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 - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * 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 + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing */ @@ -40,15 +40,15 @@ public interface AVMLockingService { DISCRETIONARY }; - + /** * 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. * @param lock The lock structure to create. */ public void lockPath(AVMLock lock); - + /** * Get a lock on a given path * @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. */ public AVMLock getLock(String webProject, String path); - + /** * Modify a lock. Null change parameters are ignored. * @param webProject The name of the web project. @@ -69,53 +69,61 @@ public interface AVMLockingService public void modifyLock(String webProject, String path, String newPath, String newStore, List usersToRemove, List usersToAdd); - + /** * Remove a lock. * @param webProject The web project the lock lives in. * @param path The store relative path of the lock. */ 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. * @param store The store name. */ public void removeStoreLocks(String store); - + /** * Get all the locks that a user owns. * @param user The name of the user. * @return The (possibly empty list) of the user's locks. */ public List getUsersLocks(String user); - + /** * Add a web project to the locking tables if it doesn't already exist. * @param webProject The web project name. */ public void addWebProject(String webProject); - + /** * Remove a web project and all associated data from the locking tables. * @param webProject The web project name. */ public void removeWebProject(String webProject); - + /** * Get all locks in a give web project. * @param webProject The web project name. * @return All the locks found. */ public List getWebProjectLocks(String webProject); - + /** * Get all locks that reside in a given store. * @param store The store name. * @return All the locks found. */ public List 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. @@ -124,7 +132,7 @@ public interface AVMLockingService * @return Whether the user has access. */ public boolean hasAccess(String webProject, String avmPath, String user); - + /** * 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. @@ -133,7 +141,7 @@ public interface AVMLockingService * @return Whether the user has access. */ public boolean hasAccess(NodeRef webProjectRef, String avmPath, String user); - + /** * Get the names of all the web projects the service knows about. * @return The list of web project names.