diff --git a/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java b/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java index ffa76add95..2ad92f8b8e 100644 --- a/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java +++ b/source/java/org/alfresco/cmis/dictionary/CMISAbstractDictionaryService.java @@ -41,6 +41,7 @@ import org.alfresco.repo.dictionary.DictionaryListener; import org.alfresco.repo.tenant.TenantService; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.ISO9075; import org.springframework.extensions.surf.util.AbstractLifecycleBean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -301,7 +302,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public CMISTypeDefinition findTypeByQueryName(String queryName) { - CMISTypeDefinition typeDef = getRegistry().typeDefsByQueryName.get(queryName.toLowerCase()); + CMISTypeDefinition typeDef = getRegistry().typeDefsByQueryName.get(ISO9075.encodeSQL(queryName.toLowerCase())); return typeDef; } @@ -311,7 +312,7 @@ public abstract class CMISAbstractDictionaryService extends AbstractLifecycleBea */ public CMISPropertyDefinition findPropertyByQueryName(String queryName) { - CMISPropertyDefinition propertyDef = getRegistry().propDefsByQueryName.get(queryName.toLowerCase()); + CMISPropertyDefinition propertyDef = getRegistry().propDefsByQueryName.get(ISO9075.encodeSQL(queryName.toLowerCase())); return propertyDef; } diff --git a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java index b6498d5a00..8c4f7fffcb 100644 --- a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java +++ b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizer.java @@ -788,9 +788,6 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl groupDisplayName = ChainingUserRegistrySynchronizer.this.authorityService.getShortName(groupName); } - // Add an entry for the parent itself, in case it is a root group - recordParentAssociationDeletion(groupName, null); - // Divide the child associations into person and group associations, dealing with case sensitivity Set newChildPersons = newPersonSet(); Set newChildGroups = new TreeSet(); @@ -821,7 +818,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl { if (!newChildPersons.remove(child)) { - // Make sure each child features as a key in the creation map + // Make sure each person with association changes features as a key in the creation map recordParentAssociationCreation(child, null); recordParentAssociationDeletion(child, groupName); } @@ -838,6 +835,8 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl // Mark as created if new else { + // Make sure each group to be created features in the association deletion map (as these are handled in the same phase) + recordParentAssociationDeletion(groupName, null); this.groupsToCreate.put(groupName, groupDisplayName); } @@ -1092,7 +1091,7 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl public void processGroups(UserRegistry userRegistry, boolean allowDeletions, boolean splitTxns) { // If we got back some groups, we have to cross reference them with the set of known authorities - if (allowDeletions || !this.groupParentAssocsToCreate.isEmpty()) + if (allowDeletions || !this.groupParentAssocsToDelete.isEmpty()) { final Set allZonePersons = newPersonSet(); final Set allZoneGroups = new TreeSet(); @@ -1141,8 +1140,9 @@ public class ChainingUserRegistrySynchronizer extends AbstractLifecycleBean impl } // Prune the group associations now that we have complete information - logRetainParentAssociations(this.groupParentAssocsToCreate, allZoneGroups); - this.groupParentAssocsToDelete.keySet().retainAll(allZoneGroups); + this.groupParentAssocsToCreate.keySet().retainAll(allZoneGroups); + logRetainParentAssociations(this.groupParentAssocsToDelete, allZoneGroups); + this.finalGroupChildAssocs.keySet().retainAll(allZoneGroups); // Pruning person associations will have to wait until we have passed over all persons and built up // this set diff --git a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java index eb0f62b630..0b521f7803 100644 --- a/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java +++ b/source/java/org/alfresco/repo/security/sync/ChainingUserRegistrySynchronizerTest.java @@ -241,7 +241,7 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase * * Z2 * G2 - U1, U3, U4, U6 - * G6 - U3, U4, G7 + * G6 - U3, U4, G7, G8 - U4, U8 * * * @throws Exception @@ -256,15 +256,17 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase newPerson("U1", "changeofemail@alfresco.com"), newPerson("U6"), newPerson("U7") }, new NodeDescription[] { - newGroup("G1", "U1", "U6", "UDangling", "G2"), newGroup("G2", "U1", "GDangling", "G1"), // test cyclic G2 <-> G1 + newGroup("G1", "U1", "U6", "UDangling", "G2"), newGroup("G2", "U1", "GDangling", "G1"), // test cyclic G2 + // <-> G1 newGroupWithDisplayName("G5", "Amazing Group", "U6", "U7", "G4") }); this.applicationContextManager.updateZone("Z2", new NodeDescription[] { - newPerson("U1", "shouldbeignored@alfresco.com"), newPerson("U5", "u5email@alfresco.com"), newPerson("U6") + newPerson("U1", "shouldbeignored@alfresco.com"), newPerson("U5", "u5email@alfresco.com"), newPerson("U6"), + newPerson("U8") }, new NodeDescription[] { - newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G7") + newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G7"), newGroup("G8", "U4", "U8") }); this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() { @@ -289,8 +291,10 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase assertExists("Z2", "U4"); assertExists("Z2", "U5"); assertEmailEquals("U5", "u5email@alfresco.com"); + assertExists("Z2", "U8"); assertExists("Z2", "G6", "U3", "U4", "G7"); assertExists("Z2", "G7"); + assertExists("Z2", "G8", "U4", "U8"); return null; } }); @@ -310,8 +314,9 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase * G6 - u3 * * Z2 - * G2 - U1, U3, U6 + * G2 - U1 * G6 - U3, G7 + * G8 - U1, U8 * * * @throws Exception @@ -329,11 +334,11 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase newGroup("G6", "u3") }), new MockUserRegistry("Z2", new NodeDescription[] { - newPerson("U1", "somenewemail@alfresco.com"), newPerson("U3"), newPerson("U6") + newPerson("U1", "somenewemail@alfresco.com"), newPerson("U3"), newPerson("U6"), newPerson("U8"), }, new NodeDescription[] { newGroup("G2", "U1", "U3", "U4", "U6"), newGroup("G6", "U3", "U4", "G7"), - newGroupWithDisplayName("G7", "Late Arrival", "U4", "U5") + newGroupWithDisplayName("G7", "Late Arrival", "U4", "U5"), newGroup("G8", "U1", "U8") })); this.synchronizer.synchronize(true, true, true); this.retryingTransactionHelper.doInTransaction(new RetryingTransactionCallback() @@ -354,8 +359,10 @@ public class ChainingUserRegistrySynchronizerTest extends TestCase assertEmailEquals("U1", "somenewemail@alfresco.com"); assertNotExists("U4"); assertNotExists("U5"); - assertExists("Z2", "G7"); + assertExists("Z2", "U8"); + assertExists("Z2", "G7"); assertGroupDisplayNameEquals("G7", "Late Arrival"); + assertExists("Z2", "G8", "U1", "U8"); return null; } }, false, true);