From 1242cc4081a07139d3f7a821461530109aa81df4 Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Tue, 5 Jul 2016 15:50:35 +0300 Subject: [PATCH 01/19] Revert "Revert "Merge branch 'feature-2.4/RM-3265_NoOptionToMoveADestroyedRecordFolder' into 'release/V2.4'"" This reverts commit 36d5dc46eaecf78ef6d253ff4b72cb43172e235b. --- .../capability/rm-capabilities-condition-context.xml | 4 ++-- .../capability/rm-capabilities-recordfolder-context.xml | 2 +- ...ition.java => MovableRecordFolderCapabilityCondition.java} | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/{MovableCapabilityCondition.java => MovableRecordFolderCapabilityCondition.java} (86%) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml index d5509295c4..e90a241f9f 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-condition-context.xml @@ -60,9 +60,9 @@ class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.TransferredCapabilityCondition"> - + class="org.alfresco.module.org_alfresco_module_rm.capability.declarative.condition.MovableRecordFolderCapabilityCondition"> - + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java similarity index 86% rename from rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java rename to rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java index 99aebc7f29..787221f457 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableCapabilityCondition.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java @@ -36,7 +36,7 @@ import org.alfresco.service.cmr.repository.NodeRef; * @since 2.4.1 * */ -public class MovableCapabilityCondition extends AbstractCapabilityCondition +public class MovableRecordFolderCapabilityCondition extends AbstractCapabilityCondition { /** @@ -47,6 +47,6 @@ public class MovableCapabilityCondition extends AbstractCapabilityCondition { if (nodeService.hasAspect(nodeRef, ASPECT_GHOSTED) && dispositionService.isDisposableItemCutoff(nodeRef)) return true; - return !dispositionService.isDisposableItemCutoff(nodeRef); + return ! (dispositionService.isDisposableItemCutoff(nodeRef) || recordFolderService.isRecordFolderClosed(nodeRef)); } } From ff2d6eb64ab25ba980a7fdf4c2b7368cccf2b5c9 Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Thu, 7 Jul 2016 16:32:26 +0300 Subject: [PATCH 02/19] RM-3265 Explore test failures cause. Remove condition for closed folders. --- .../condition/MovableRecordFolderCapabilityCondition.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java index 787221f457..de741d1604 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java @@ -47,6 +47,6 @@ public class MovableRecordFolderCapabilityCondition extends AbstractCapabilityCo { if (nodeService.hasAspect(nodeRef, ASPECT_GHOSTED) && dispositionService.isDisposableItemCutoff(nodeRef)) return true; - return ! (dispositionService.isDisposableItemCutoff(nodeRef) || recordFolderService.isRecordFolderClosed(nodeRef)); + return ! (dispositionService.isDisposableItemCutoff(nodeRef) /*|| recordFolderService.isRecordFolderClosed(nodeRef)*/); } } From ca77b1c782971a2724c9ede35da27461ed8c728b Mon Sep 17 00:00:00 2001 From: Roxana Dina Date: Tue, 12 Jul 2016 16:32:47 +0300 Subject: [PATCH 03/19] RM-3265 Explore test failures cause. Introduce "kinds" property in moveRecordFolderCapability bean. --- .../capability/rm-capabilities-recordfolder-context.xml | 5 +++++ .../condition/MovableRecordFolderCapabilityCondition.java | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml index 74f1183507..4a24c03715 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/capability/rm-capabilities-recordfolder-context.xml @@ -122,6 +122,11 @@ + + + RECORD_FOLDER + + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java index de741d1604..787221f457 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java @@ -47,6 +47,6 @@ public class MovableRecordFolderCapabilityCondition extends AbstractCapabilityCo { if (nodeService.hasAspect(nodeRef, ASPECT_GHOSTED) && dispositionService.isDisposableItemCutoff(nodeRef)) return true; - return ! (dispositionService.isDisposableItemCutoff(nodeRef) /*|| recordFolderService.isRecordFolderClosed(nodeRef)*/); + return ! (dispositionService.isDisposableItemCutoff(nodeRef) || recordFolderService.isRecordFolderClosed(nodeRef)); } } From fab6cdfe9bf6297fcb0f44efd556de523216760f Mon Sep 17 00:00:00 2001 From: Silviu Dinuta Date: Thu, 9 Mar 2017 16:27:50 +0200 Subject: [PATCH 04/19] RM-4163: added integration test for scenario provided by Roy and got the fix from master --- .../RecordComponentIdentifierAspect.java | 2 +- .../security/ExtendedSecurityServiceImpl.java | 218 +++++++++--------- .../test/integration/issue/RM4163Test.java | 207 +++++++++++++++++ 3 files changed, 322 insertions(+), 105 deletions(-) create mode 100644 rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4163Test.java diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java index c9faddb513..54534e2992 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/model/rma/aspect/RecordComponentIdentifierAspect.java @@ -230,7 +230,7 @@ public class RecordComponentIdentifierAspect extends BaseBehaviourBean // Do a blanket removal in case this is a contextual nodes attributeService.removeAttributes(CONTEXT_VALUE, nodeRef); } - else + else if(!beforeId.equals(afterId)) { // This is a full update attributeService.updateOrCreateAttribute( diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityServiceImpl.java index 2303162650..706c3cdb73 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/security/ExtendedSecurityServiceImpl.java @@ -46,6 +46,7 @@ import org.alfresco.query.PagingResults; import org.alfresco.repo.security.authority.RMAuthority; import org.alfresco.repo.transaction.RetryingTransactionHelper; import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessPermission; import org.alfresco.service.cmr.security.AuthorityService; @@ -83,13 +84,13 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl /** File plan role service */ private FilePlanRoleService filePlanRoleService; - + /** authority service */ private AuthorityService authorityService; - + /** permission service */ private PermissionService permissionService; - + /** transaction service */ private TransactionService transactionService; @@ -108,7 +109,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { this.filePlanRoleService = filePlanRoleService; } - + /** * @param authorityService authority service */ @@ -116,7 +117,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { this.authorityService = authorityService; } - + /** * @param permissionService permission service */ @@ -124,7 +125,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { this.permissionService = permissionService; } - + /** * @param transactionService transaction service */ @@ -132,7 +133,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { this.transactionService = transactionService; } - + /** * Application context refresh event handler */ @@ -148,12 +149,12 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { authorityService.createAuthority(AuthorityType.GROUP, ROOT_IPR_GROUP, ROOT_IPR_GROUP, Collections.singleton(RMAuthority.ZONE_APP_RM)); } - + return null; } }); } - + /** * Get root IPR group name */ @@ -179,15 +180,15 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl public Set getReaders(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); - + Set result = Collections.EMPTY_SET; Pair iprGroups = getIPRGroups(nodeRef); if (iprGroups != null) { result = getAuthorities(iprGroups.getFirst()); } - - return result; + + return result; } /** @@ -198,20 +199,20 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl public Set getWriters(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); - + Set result = Collections.EMPTY_SET; Pair iprGroups = getIPRGroups(nodeRef); if (iprGroups != null) { result = getAuthorities(iprGroups.getSecond()); } - - return result; + + return result; } - + /** * Helper to get authorities for a given group - * + * * @param group group name * @return Set immediate authorities */ @@ -221,7 +222,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl result.addAll(authorityService.getContainedAuthorities(null, group, true)); return result; } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService#set(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.util.Pair) */ @@ -231,7 +232,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl ParameterCheck.mandatory("nodeRef", nodeRef); set(nodeRef, readersAndWriters.getFirst(), readersAndWriters.getSecond()); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService#set(org.alfresco.service.cmr.repository.NodeRef, java.util.Set, java.util.Set) */ @@ -239,21 +240,21 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl public void set(NodeRef nodeRef, Set readers, Set writers) { ParameterCheck.mandatory("nodeRef", nodeRef); - + // remove existing extended security, assuming there is any remove(nodeRef); - + // find groups Pair iprGroups = createOrFindIPRGroups(readers, writers); - + // assign groups to correct fileplan roles NodeRef filePlan = filePlanService.getFilePlan(nodeRef); filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_READERS, iprGroups.getFirst()); filePlanRoleService.assignRoleToAuthority(filePlan, FilePlanRoleService.ROLE_EXTENDED_WRITERS, iprGroups.getSecond()); - + // assign groups to node assignIPRGroupsToNode(iprGroups, nodeRef); - + // apply the readers to any renditions of the content if (isRecord(nodeRef)) { @@ -263,14 +264,14 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl NodeRef child = assoc.getChildRef(); assignIPRGroupsToNode(iprGroups, child); } - } + } } - + /** * Get the IPR groups associated with a given node reference. *

* Return null if none found. - * + * * @param nodeRef node reference * @return Pair where first is the read group and second if the write group, null if none found */ @@ -279,7 +280,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl Pair result = null; String iprReaderGroup = null; String iprWriterGroup = null; - + // get all the set permissions Set permissions = permissionService.getAllSetPermissions(nodeRef); for (AccessPermission permission : permissions) @@ -288,36 +289,36 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl if (permission.getAuthority().startsWith(GROUP_PREFIX + READER_GROUP_PREFIX)) { iprReaderGroup = permission.getAuthority(); - } + } // look for the presence of the writer group else if (permission.getAuthority().startsWith(GROUP_PREFIX + WRITER_GROUP_PREFIX)) { iprWriterGroup = permission.getAuthority(); } } - + // assuming the are both present then return if (iprReaderGroup != null && iprWriterGroup != null) { result = new Pair(iprReaderGroup, iprWriterGroup); } - + return result; } - + /** * Given a set of readers and writers find or create the appropriate IPR groups. *

- * The IPR groups are named with hashes of the authority lists in order to reduce + * The IPR groups are named with hashes of the authority lists in order to reduce * the set of groups that require exact match. A further index is used to handle * a situation where there is a hash clash, but a difference in the authority lists. *

* When no match is found the groups are created. Once created - * + * * @param filePlan file plan * @param readers authorities with read * @param writers authorities with write - * @return Pair where first is the full name of the read group and + * @return Pair where first is the full name of the read group and * second is the full name of the write group */ private Pair createOrFindIPRGroups(Set readers, Set writers) @@ -326,10 +327,10 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl createOrFindIPRGroup(READER_GROUP_PREFIX, readers), createOrFindIPRGroup(WRITER_GROUP_PREFIX, writers)); } - + /** * Create or find an IPR group based on the provided prefix and authorities. - * + * * @param groupPrefix group prefix * @param authorities authorities * @return String full group name @@ -337,10 +338,10 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl private String createOrFindIPRGroup(String groupPrefix, Set authorities) { String group = null; - - // find group or determine what the next index is if no group exists or there is a clash + + // find group or determine what the next index is if no group exists or there is a clash Pair groupResult = findIPRGroup(groupPrefix, authorities); - + if (groupResult.getFirst() == null) { group = createIPRGroup(groupPrefix, authorities, groupResult.getSecond()); @@ -349,16 +350,16 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { group = groupResult.getFirst(); } - + return group; } - + /** * Given a group name prefix and the authorities, finds the exact match existing group. *

- * If the group does not exist then the group returned is null and the index shows the next available + * If the group does not exist then the group returned is null and the index shows the next available * group index for creation. - * + * * @param groupPrefix group name prefix * @param authorities authorities * @return Pair where first is the name of the found group, null if none found and second @@ -370,24 +371,24 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl int nextGroupIndex = 0; boolean hasMoreItems = true; int pageCount = 0; - + // determine the short name prefix String groupShortNamePrefix = getIPRGroupPrefixShortName(groupPrefix, authorities); - + // iterate over the authorities to find a match while (hasMoreItems == true) - { + { // get matching authorities - PagingResults results = authorityService.getAuthorities(AuthorityType.GROUP, - RMAuthority.ZONE_APP_RM, + PagingResults results = authorityService.getAuthorities(AuthorityType.GROUP, + RMAuthority.ZONE_APP_RM, groupShortNamePrefix, - false, - false, + false, + false, new PagingRequest(MAX_ITEMS*pageCount, MAX_ITEMS)); - + // record the total count nextGroupIndex = nextGroupIndex + results.getPage().size(); - + // see if any of the matching groups exactly match for (String group : results.getPage()) { @@ -396,35 +397,35 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { iprGroup = group; break; - } + } } - + // determine if there are any more pages to inspect hasMoreItems = results.hasMoreItems(); pageCount ++; } - + return new Pair(iprGroup, nextGroupIndex); } - + /** * Determines whether a group exactly matches a list of authorities. - * + * * @param authorities list of authorities - * @param group group + * @param group group * @return */ private boolean isIPRGroupTrueMatch(String group, Set authorities) - { + { Set contained = authorityService.getContainedAuthorities(null, group, true); return contained.equals(authorities); } - + /** * Get IPR group prefix short name. *

* 'package' scope to help testing. - * + * * @param prefix prefix * @param authorities authorities * @return String group prefix short name @@ -434,17 +435,17 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl StringBuilder builder = new StringBuilder(128) .append(prefix) .append(getAuthoritySetHashCode(authorities)); - + return builder.toString(); } - + /** * Get IPR group short name. *

* Note this excludes the "GROUP_" prefix. *

* 'package' scope to help testing. - * + * * @param prefix prefix * @param readers read authorities * @param writers write authorities @@ -455,12 +456,12 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { return getIPRGroupShortName(prefix, authorities, Integer.toString(index)); } - + /** * Get IPR group short name. *

* Note this excludes the "GROUP_" prefix. - * + * * @param prefix prefix * @param readers read authorities * @param writers write authorities @@ -472,13 +473,13 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl StringBuilder builder = new StringBuilder(128) .append(getIPRGroupPrefixShortName(prefix, authorities)) .append(index); - + return builder.toString(); } - + /** * Gets the hashcode value of a set of authorities. - * + * * @param authorities set of authorities * @return int hash code */ @@ -487,14 +488,14 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl int result = 0; if (authorities != null && !authorities.isEmpty()) { - result = StringUtils.join(authorities.toArray(), "").hashCode(); + result = StringUtils.join(authorities.toArray(), "").hashCode(); } return result; } - + /** * Creates a new IPR group. - * + * * @param groupNamePrefix group name prefix * @param children child authorities * @param index group index @@ -503,35 +504,44 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl private String createIPRGroup(String groupNamePrefix, Set children, int index) { ParameterCheck.mandatory("groupNamePrefix", groupNamePrefix); - + // get the group name String groupShortName = getIPRGroupShortName(groupNamePrefix, children, index); - + // create group - String group = authorityService.createAuthority(AuthorityType.GROUP, groupShortName, groupShortName, Collections.singleton(RMAuthority.ZONE_APP_RM)); - - // add root parent - authorityService.addAuthority(getRootIRPGroup(), group); - - // add children if provided - if (children != null) + String group; + try { - for (String child : children) + group = authorityService.createAuthority(AuthorityType.GROUP, groupShortName, groupShortName, Collections.singleton(RMAuthority.ZONE_APP_RM)); + + // add root parent + authorityService.addAuthority(getRootIRPGroup(), group); + + // add children if provided + if (children != null) { - if (authorityService.authorityExists(child) && - !PermissionService.ALL_AUTHORITIES.equals(child)) + for (String child : children) { - authorityService.addAuthority(group, child); + if (authorityService.authorityExists(child) && + !PermissionService.ALL_AUTHORITIES.equals(child)) + { + authorityService.addAuthority(group, child); + } } } } - + catch(DuplicateChildNodeNameException ex) + { + // the group was concurrently created + group = authorityService.getName(AuthorityType.GROUP, groupShortName); + } + return group; } - + /** * Assign IPR groups to a node reference with the correct permissions. - * + * * @param iprGroups iprGroups, first read and second write * @param nodeRef node reference */ @@ -540,7 +550,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl permissionService.setPermission(nodeRef, iprGroups.getFirst(), RMPermissionModel.READ_RECORDS, true); permissionService.setPermission(nodeRef, iprGroups.getSecond(), RMPermissionModel.FILING, true); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService#remove(org.alfresco.service.cmr.repository.NodeRef) */ @@ -548,13 +558,13 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl public void remove(NodeRef nodeRef) { ParameterCheck.mandatory("nodeRef", nodeRef); - + Pair iprGroups = getIPRGroups(nodeRef); if (iprGroups != null) { // remove any extended security that might be present clearPermissions(nodeRef, iprGroups); - + // remove the readers from any renditions of the content if (isRecord(nodeRef)) { @@ -570,16 +580,16 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl /** * Clear the nodes IPR permissions - * + * * @param nodeRef node reference */ private void clearPermissions(NodeRef nodeRef, Pair iprGroups) { // remove group permissions from node permissionService.clearPermission(nodeRef, iprGroups.getFirst()); - permissionService.clearPermission(nodeRef, iprGroups.getSecond()); - } - + permissionService.clearPermission(nodeRef, iprGroups.getSecond()); + } + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#getExtendedReaders(org.alfresco.service.cmr.repository.NodeRef) */ @@ -587,7 +597,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { return getReaders(nodeRef); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#getExtendedWriters(org.alfresco.service.cmr.repository.NodeRef) */ @@ -595,15 +605,15 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { return getWriters(nodeRef); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#addExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef, java.util.Set, java.util.Set) */ @Override @Deprecated public void addExtendedSecurity(NodeRef nodeRef, Set readers, Set writers) { - set(nodeRef, readers, writers); + set(nodeRef, readers, writers); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#addExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef, java.util.Set, java.util.Set, boolean) */ @@ -611,7 +621,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { set(nodeRef, readers, writers); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#removeAllExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef) */ @@ -619,7 +629,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl { remove(nodeRef); } - + /** * @see org.alfresco.module.org_alfresco_module_rm.security.DeprecatedExtendedSecurityService#removeExtendedSecurity(org.alfresco.service.cmr.repository.NodeRef, java.util.Set, java.util.Set) */ @@ -633,7 +643,7 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl */ @Override @Deprecated public void removeExtendedSecurity(NodeRef nodeRef, Set readers, Setwriters, boolean applyToParents) { - remove(nodeRef); + remove(nodeRef); } /** @@ -641,6 +651,6 @@ public class ExtendedSecurityServiceImpl extends ServiceBaseImpl */ @Override @Deprecated public void removeAllExtendedSecurity(NodeRef nodeRef, boolean applyToParents) { - remove(nodeRef); + remove(nodeRef); } } diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4163Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4163Test.java new file mode 100644 index 0000000000..660f04194f --- /dev/null +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4163Test.java @@ -0,0 +1,207 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2017 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.dm.CreateRecordAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.FileToAction; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; +import org.alfresco.service.cmr.action.Action; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.rule.Rule; +import org.alfresco.service.cmr.rule.RuleService; +import org.alfresco.service.cmr.rule.RuleType; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * System test for RM-4163 + * + * @author Silviu Dinuta + * @since 2.4.1 + */ +public class RM4163Test extends BaseRMTestCase +{ + private RuleService ruleService; + private NodeRef ruleFolder; + private NodeRef nodeRefCategory1; + + @Override + protected void initServices() + { + super.initServices(); + + ruleService = (RuleService) applicationContext.getBean("RuleService"); + } + + @Override + protected boolean isCollaborationSiteTest() + { + return true; + } + + @Override + protected boolean isRecordTest() + { + return true; + } + + public void testDeclareRecordsConcurently() throws Exception + { + doTestInTransaction(new Test() + { + @Override + public Void run() + { + // create the folder + ruleFolder = fileFolderService.create(documentLibrary, "mytestfolder", ContentModel.TYPE_FOLDER) + .getNodeRef(); + + // create record category + nodeRefCategory1 = filePlanService.createRecordCategory(filePlan, "category1"); + + //define declare as record rule and apply it to the created folder from documentLibrary + Action action = actionService.createAction(CreateRecordAction.NAME); + action.setParameterValue(CreateRecordAction.PARAM_FILE_PLAN, filePlan); + + Rule rule = new Rule(); + rule.setRuleType(RuleType.INBOUND); + rule.setTitle("declareAsRecordRule"); + rule.setAction(action); + rule.setExecuteAsynchronously(true); + ruleService.saveRule(ruleFolder, rule); + + //define filing rule and apply it to unfiled record container + Action fileAction = actionService.createAction(FileToAction.NAME); + fileAction.setParameterValue(FileToAction.PARAM_PATH, + "/category1/{node.cm:description}"); + fileAction.setParameterValue(FileToAction.PARAM_CREATE_RECORD_PATH, true); + + Rule fileRule = new Rule(); + fileRule.setRuleType(RuleType.INBOUND); + fileRule.setTitle("filingRule"); + fileRule.setAction(fileAction); + fileRule.setExecuteAsynchronously(true); + ruleService.saveRule(filePlanService.getUnfiledContainer(filePlan), fileRule); + + return null; + } + + @Override + public void test(Void result) throws Exception + { + assertFalse(ruleService.getRules(ruleFolder).isEmpty()); + } + }); + + //create 4 documents in documentLibrary + List documents = new ArrayList(4); + documents.addAll(doTestInTransaction(new Test>() + { + @Override + public List run() throws Exception + { + List documents = new ArrayList(4); + NodeRef document = createFile(documentLibrary, "document1.txt", "desc1", ContentModel.TYPE_CONTENT); + documents.add(document); + document = createFile(documentLibrary, "document2.txt", "desc2", ContentModel.TYPE_CONTENT); + documents.add(document); + document = createFile(documentLibrary, "document3.txt", "desc1", ContentModel.TYPE_CONTENT); + documents.add(document); + document = createFile(documentLibrary, "document4.txt", "desc1", ContentModel.TYPE_CONTENT); + documents.add(document); + return documents; + } + })); + + //move created documents in the folder that has Declare as Record rule + final Iterator temp = documents.iterator(); + doTestInTransaction(new Test() + { + @Override + public Void run() throws Exception + { + while (temp.hasNext()) + { + NodeRef document = temp.next(); + fileFolderService.move(document, ruleFolder, null); + } + return null; + } + }); + + //give enough time for filing all records + Thread.sleep(5000); + + //check that target category has in created record folders 4 records + Integer numberOfRecords = AuthenticationUtil.runAsSystem(new RunAsWork() + { + + @Override + public Integer doWork() throws Exception + { + List containedRecordFolders = filePlanService.getContainedRecordFolders(nodeRefCategory1); + int numberOfRecords = 0; + for(NodeRef recordFolder : containedRecordFolders) + { + numberOfRecords = numberOfRecords + fileFolderService.list(recordFolder).size(); + } + return numberOfRecords; + } + }); + assertEquals(4, numberOfRecords.intValue()); + } + + private NodeRef createFile(NodeRef parentNodeRef, String name, String descrption, QName typeQName) + { + Map properties = new HashMap(11); + properties.put(ContentModel.PROP_NAME, (Serializable) name); + properties.put(ContentModel.PROP_DESCRIPTION, (Serializable) descrption); + QName assocQName = QName.createQName( + NamespaceService.CONTENT_MODEL_1_0_URI, + QName.createValidLocalName(name)); + ChildAssociationRef assocRef = nodeService.createNode( + parentNodeRef, + ContentModel.ASSOC_CONTAINS, + assocQName, + typeQName, + properties); + NodeRef nodeRef = assocRef.getChildRef(); + return nodeRef; + } +} From b19235004d7390116200bc64f7d7dd19037dfb8b Mon Sep 17 00:00:00 2001 From: David Webster Date: Thu, 9 Mar 2017 17:02:39 +0000 Subject: [PATCH 05/19] MNT-17550: Release 2.2.0.3 --- pom.xml | 2 +- rm-server/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 197172d10a..10531c872e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.0.3-SNAPSHOT + 2.2.0.3 Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 947f6ac454..ac7eee6f0f 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.0.3-SNAPSHOT + 2.2.0.3 4.0.0 alfresco-rm-server From 50bb522a3e8b335477d6f56b41876030613c51df Mon Sep 17 00:00:00 2001 From: David Webster Date: Fri, 10 Mar 2017 14:48:11 +0000 Subject: [PATCH 06/19] Update versions following release of 2.2.0.3 --- pom.xml | 2 +- .../alfresco/module/org_alfresco_module_rm/module.properties | 2 +- rm-server/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 10531c872e..778fbfe1ef 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.alfresco alfresco-rm-parent pom - 2.2.0.3 + 2.2.0.4-SNAPSHOT Alfresco Records Management http://www.alfresco.org/ diff --git a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties index f5c791e7ba..704d924b74 100644 --- a/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties +++ b/rm-server/config/alfresco/module/org_alfresco_module_rm/module.properties @@ -6,6 +6,6 @@ module.aliases=org_alfresco_module_dod5015 module.title=Records Management module.description=Alfresco Record Management Extension -module.version=2.2.0.3 +module.version=2.2.0.4 module.repo.version.min=4.2 \ No newline at end of file diff --git a/rm-server/pom.xml b/rm-server/pom.xml index ac7eee6f0f..9d9c8bad15 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -5,7 +5,7 @@ org.alfresco alfresco-rm-parent - 2.2.0.3 + 2.2.0.4-SNAPSHOT 4.0.0 alfresco-rm-server From 7dce59e4c8a7516c56fab574f5d99472d902c07a Mon Sep 17 00:00:00 2001 From: David Webster Date: Thu, 9 Mar 2017 10:55:37 +0000 Subject: [PATCH 07/19] MNT-17550: Update POM to work around build issue (BDE-996) --- rm-server/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 12b59dee39..a8037e8dbe 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -195,6 +195,12 @@ config + + org.testng + testng + 5.14.10 + test + junit junit From 407e1f1e657c86fde41fc36102afe861e6aac653 Mon Sep 17 00:00:00 2001 From: Samuel Langlois Date: Thu, 9 Mar 2017 11:37:13 +0000 Subject: [PATCH 08/19] MNT-17550/BDE-996 Fix TestNG version to 6.10 --- rm-server/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rm-server/pom.xml b/rm-server/pom.xml index a8037e8dbe..611d48f9c7 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -198,7 +198,7 @@ org.testng testng - 5.14.10 + 6.10 test From 9950f4868c199a5ebdb27b7ac10125b5d6d22221 Mon Sep 17 00:00:00 2001 From: David Webster Date: Thu, 9 Mar 2017 10:55:37 +0000 Subject: [PATCH 09/19] MNT-17550: Update POM to work around build issue (BDE-996) --- rm-server/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rm-server/pom.xml b/rm-server/pom.xml index a61504994e..a237fe7ea5 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -189,6 +189,12 @@ ${alfresco.base.version} + + org.testng + testng + 5.14.10 + test + junit junit From ff00888ac4ca983409f2844a5002b94896c1ccf6 Mon Sep 17 00:00:00 2001 From: Samuel Langlois Date: Thu, 9 Mar 2017 11:37:13 +0000 Subject: [PATCH 10/19] MNT-17550/BDE-996 Fix TestNG version to 6.10 --- rm-server/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rm-server/pom.xml b/rm-server/pom.xml index a237fe7ea5..aa544e2621 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -192,7 +192,7 @@ org.testng testng - 5.14.10 + 6.10 test @@ -261,4 +261,4 @@ test - \ No newline at end of file + From 0512d6a3083362e25120f8cb70f0c6c3cdfd2782 Mon Sep 17 00:00:00 2001 From: David Webster Date: Fri, 10 Mar 2017 16:00:23 +0000 Subject: [PATCH 11/19] MNT-17550: Remove unnecessary file changes (should have been a record only merge from V2.3.0.x) --- rm-server/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rm-server/pom.xml b/rm-server/pom.xml index 4179a6006d..8803399995 100644 --- a/rm-server/pom.xml +++ b/rm-server/pom.xml @@ -215,12 +215,6 @@ 1.2.7 test - - org.testng - testng - 6.10 - test - junit junit From a9375ada87379e6bfe0b8508ad8e2607476054ea Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Fri, 10 Mar 2017 17:45:48 +0000 Subject: [PATCH 12/19] RM-2396 (Upload record via WebDAV fails with org.alfresco.repo.security.permissions.AccessDeniedException) --- .../record/RecordServiceImpl.java | 195 +++++------------- 1 file changed, 50 insertions(+), 145 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index d9b351e331..a920abedae 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -29,6 +29,9 @@ package org.alfresco.module.org_alfresco_module_rm.record; import static com.google.common.collect.Lists.newArrayList; +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.FIRST_EVENT; +import static org.alfresco.repo.policy.annotation.BehaviourKind.ASSOCIATION; + import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -70,9 +73,7 @@ import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityServi import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService; import org.alfresco.repo.node.NodeServicePolicies; -import org.alfresco.repo.policy.Behaviour.NotificationFrequency; import org.alfresco.repo.policy.ClassPolicyDelegate; -import org.alfresco.repo.policy.JavaBehaviour; import org.alfresco.repo.policy.PolicyComponent; import org.alfresco.repo.policy.annotation.Behaviour; import org.alfresco.repo.policy.annotation.BehaviourBean; @@ -84,16 +85,13 @@ import org.alfresco.repo.security.permissions.impl.ExtendedPermissionService; import org.alfresco.service.cmr.dictionary.AspectDefinition; import org.alfresco.service.cmr.dictionary.ClassDefinition; import org.alfresco.service.cmr.dictionary.PropertyDefinition; -import org.alfresco.service.cmr.model.FileExistsException; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ChildAssociationRef; -import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; -import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.rule.RuleService; import org.alfresco.service.cmr.security.AccessPermission; @@ -128,7 +126,6 @@ public class RecordServiceImpl extends BaseBehaviourBean RecordsManagementModel, RecordsManagementCustomModel, NodeServicePolicies.OnCreateChildAssociationPolicy, - NodeServicePolicies.OnAddAspectPolicy, NodeServicePolicies.OnRemoveAspectPolicy, NodeServicePolicies.OnUpdatePropertiesPolicy { @@ -137,7 +134,6 @@ public class RecordServiceImpl extends BaseBehaviourBean /** transation data key */ private static final String KEY_IGNORE_ON_UPDATE = "ignoreOnUpdate"; - private static final String KEY_PENDING_FILLING = "pendingFilling"; public static final String KEY_NEW_RECORDS = "newRecords"; /** I18N */ @@ -249,12 +245,6 @@ public class RecordServiceImpl extends BaseBehaviourBean private ClassPolicyDelegate beforeFileRecord; private ClassPolicyDelegate onFileRecord; - /** Behaviours */ - private JavaBehaviour onCreateChildAssociation = new JavaBehaviour( - this, - "onCreateChildAssociation", - NotificationFrequency.FIRST_EVENT); - /** * @param identifierService identifier service */ @@ -407,13 +397,6 @@ public class RecordServiceImpl extends BaseBehaviourBean // bind policies beforeFileRecord = policyComponent.registerClassPolicy(BeforeFileRecord.class); onFileRecord = policyComponent.registerClassPolicy(OnFileRecord.class); - - // bind behaviours - policyComponent.bindAssociationBehaviour( - NodeServicePolicies.OnCreateChildAssociationPolicy.QNAME, - TYPE_RECORD_FOLDER, - ContentModel.ASSOC_CONTAINS, - onCreateChildAssociation); } /** @@ -427,82 +410,41 @@ public class RecordServiceImpl extends BaseBehaviourBean ) public void onRemoveAspect(NodeRef nodeRef, QName aspect) { - - if (nodeService.hasAspect(nodeRef, ASPECT_RECORD)) + if (nodeService.hasAspect(nodeRef, ASPECT_RECORD) && !nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN)) { - ContentData contentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT); + // get the record id + String recordId = (String) nodeService.getProperty(nodeRef, PROP_IDENTIFIER); - // Only switch name back to the format of "name (identifierId)" if content size is non-zero, else leave it as the original name to avoid CIFS shuffling issues. - if (contentData != null && contentData.getSize() > 0) + // get the record name + String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + + // rename the record + int dotIndex = name.lastIndexOf('.'); + String prefix = name; + String postfix = ""; + if (dotIndex > 0) { - switchNames(nodeRef); + prefix = name.substring(0, dotIndex); + postfix = name.substring(dotIndex); } - } - else - { - // check whether filling is pending aspect removal - Set pendingFilling = transactionalResourceHelper.getSet(KEY_PENDING_FILLING); - if (pendingFilling.contains(nodeRef)) + String recordName = prefix + " (" + recordId + ")" + postfix; + behaviourFilter.disableBehaviour(); + try { - file(nodeRef); + fileFolderService.rename(nodeRef, recordName); } - } - } - - /** - * @see org.alfresco.repo.node.NodeServicePolicies.OnAddAspectPolicy#onAddAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) - */ - @Override - @Behaviour - ( - kind = BehaviourKind.CLASS, - type = "sys:noContent" - ) - public void onAddAspect(NodeRef nodeRef, QName aspect) - { - switchNames(nodeRef); - } - - /** - * Helper method to switch the name of the record around. Used to support record creation via - * file protocols. - * - * @param nodeRef node reference (record) - */ - private void switchNames(NodeRef nodeRef) - { - try - { - if (nodeService.hasAspect(nodeRef, ASPECT_RECORD)) + catch (FileNotFoundException e) { - String origionalName = (String)nodeService.getProperty(nodeRef, PROP_ORIGIONAL_NAME); - if (origionalName != null) - { - String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); - fileFolderService.rename(nodeRef, origionalName); - nodeService.setProperty(nodeRef, PROP_ORIGIONAL_NAME, name); - } + throw new AlfrescoRuntimeException("Unable to make record, because rename failed.", e); } - } - catch (FileExistsException e) - { + finally + { + behaviourFilter.enableBehaviour(); + } + if (logger.isDebugEnabled()) { - logger.debug(e.getMessage()); - } - } - catch (InvalidNodeRefException e) - { - if (logger.isDebugEnabled()) - { - logger.debug(e.getMessage()); - } - } - catch (FileNotFoundException e) - { - if (logger.isDebugEnabled()) - { - logger.debug(e.getMessage()); + logger.debug("Rename " + name + " to " + recordName); } } } @@ -513,6 +455,12 @@ public class RecordServiceImpl extends BaseBehaviourBean * @see org.alfresco.repo.node.NodeServicePolicies.OnCreateChildAssociationPolicy#onCreateChildAssociation(org.alfresco.service.cmr.repository.ChildAssociationRef, boolean) */ @Override + @Behaviour + ( + kind = ASSOCIATION, + type = "rma:recordFolder", + notificationFrequency = FIRST_EVENT + ) public void onCreateChildAssociation(final ChildAssociationRef childAssocRef, final boolean bNew) { AuthenticationUtil.runAs(new RunAsWork() @@ -520,7 +468,6 @@ public class RecordServiceImpl extends BaseBehaviourBean @Override public Void doWork() { - onCreateChildAssociation.disable(); try { NodeRef nodeRef = childAssocRef.getChildRef(); @@ -529,38 +476,29 @@ public class RecordServiceImpl extends BaseBehaviourBean !nodeService.getType(nodeRef).equals(TYPE_RECORD_FOLDER) && !nodeService.getType(nodeRef).equals(TYPE_RECORD_CATEGORY)) { - if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_NO_CONTENT)) + // store information about the 'new' record in the transaction + // @since 2.3 + // @see https://issues.alfresco.com/jira/browse/RM-1956 + if (bNew) { - // we need to postpone filling until the NO_CONTENT aspect is removed - Set pendingFilling = transactionalResourceHelper.getSet(KEY_PENDING_FILLING); - pendingFilling.add(nodeRef); + Set newRecords = transactionalResourceHelper.getSet(KEY_NEW_RECORDS); + newRecords.add(nodeRef); } else { - // store information about the 'new' record in the transaction - // @since 2.3 - // @see https://issues.alfresco.com/jira/browse/RM-1956 - if (bNew) + // if we are linking a record + NodeRef parentNodeRef = childAssocRef.getParentRef(); + if (isRecord(nodeRef) && isRecordFolder(parentNodeRef)) { - Set newRecords = transactionalResourceHelper.getSet(KEY_NEW_RECORDS); - newRecords.add(nodeRef); + // validate the link conditions + validateLinkConditions(nodeRef, parentNodeRef); } - else - { - // if we are linking a record - NodeRef parentNodeRef = childAssocRef.getParentRef(); - if (isRecord(nodeRef) && isRecordFolder(parentNodeRef)) - { - // validate the link conditions - validateLinkConditions(nodeRef, parentNodeRef); - } - } - - // create and file the content as a record - file(nodeRef); - // recalculate disposition schedule for the record when linking it - dispositionService.recalculateNextDispositionStep(nodeRef); } + + // create and file the content as a record + file(nodeRef); + // recalculate disposition schedule for the record when linking it + dispositionService.recalculateNextDispositionStep(nodeRef); } } catch (RecordLinkRuntimeException e) @@ -576,10 +514,6 @@ public class RecordServiceImpl extends BaseBehaviourBean logger.warn("Unable to file pending record.", e); } } - finally - { - onCreateChildAssociation.enable(); - } return null; } @@ -1184,31 +1118,6 @@ public class RecordServiceImpl extends BaseBehaviourBean // get the record name String name = (String)nodeService.getProperty(document, ContentModel.PROP_NAME); - // rename the record - int dotIndex = name.lastIndexOf('.'); - String prefix = name; - String postfix = ""; - if (dotIndex != -1) - { - prefix = name.substring(0, dotIndex); - postfix = name.substring(dotIndex); - } - String recordName = prefix + " (" + recordId + ")" + postfix; - behaviourFilter.disableBehaviour(); - try - { - fileFolderService.rename(document, recordName); - } - finally - { - behaviourFilter.enableBehaviour(); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Rename " + name + " to " + recordName); - } - // add the record aspect Map props = new HashMap(2); props.put(PROP_IDENTIFIER, recordId); @@ -1221,10 +1130,6 @@ public class RecordServiceImpl extends BaseBehaviourBean // remove the owner ownableService.setOwner(document, OwnableService.NO_OWNER); } - catch (FileNotFoundException e) - { - throw new AlfrescoRuntimeException("Unable to make record, because rename failed.", e); - } finally { ruleService.enableRules(); From 98628c75de17e4ef1ba265277e3ab7c1162202e5 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Sun, 12 Mar 2017 21:00:19 +0000 Subject: [PATCH 13/19] RM-2396 (Upload record via WebDAV fails with org.alfresco.repo.security.permissions.AccessDeniedException) --- .../record/RecordServiceImpl.java | 115 ++++++++++-------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index a920abedae..f9c6b22383 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -30,7 +30,9 @@ package org.alfresco.module.org_alfresco_module_rm.record; import static com.google.common.collect.Lists.newArrayList; import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.FIRST_EVENT; +import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.TRANSACTION_COMMIT; import static org.alfresco.repo.policy.annotation.BehaviourKind.ASSOCIATION; +import static org.apache.commons.lang.StringUtils.isNotBlank; import java.io.Serializable; import java.util.ArrayList; @@ -72,6 +74,7 @@ import org.alfresco.module.org_alfresco_module_rm.role.Role; import org.alfresco.module.org_alfresco_module_rm.security.ExtendedSecurityService; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionModel; import org.alfresco.module.org_alfresco_module_rm.version.RecordableVersionService; +import org.alfresco.repo.content.ContentServicePolicies; import org.alfresco.repo.node.NodeServicePolicies; import org.alfresco.repo.policy.ClassPolicyDelegate; import org.alfresco.repo.policy.PolicyComponent; @@ -126,8 +129,8 @@ public class RecordServiceImpl extends BaseBehaviourBean RecordsManagementModel, RecordsManagementCustomModel, NodeServicePolicies.OnCreateChildAssociationPolicy, - NodeServicePolicies.OnRemoveAspectPolicy, - NodeServicePolicies.OnUpdatePropertiesPolicy + NodeServicePolicies.OnUpdatePropertiesPolicy, + ContentServicePolicies.OnContentUpdatePolicy { /** Logger */ private static Log logger = LogFactory.getLog(RecordServiceImpl.class); @@ -399,56 +402,6 @@ public class RecordServiceImpl extends BaseBehaviourBean onFileRecord = policyComponent.registerClassPolicy(OnFileRecord.class); } - /** - * @see org.alfresco.repo.node.NodeServicePolicies.OnRemoveAspectPolicy#onRemoveAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName) - */ - @Override - @Behaviour - ( - kind = BehaviourKind.CLASS, - type = "sys:noContent" - ) - public void onRemoveAspect(NodeRef nodeRef, QName aspect) - { - if (nodeService.hasAspect(nodeRef, ASPECT_RECORD) && !nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN)) - { - // get the record id - String recordId = (String) nodeService.getProperty(nodeRef, PROP_IDENTIFIER); - - // get the record name - String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); - - // rename the record - int dotIndex = name.lastIndexOf('.'); - String prefix = name; - String postfix = ""; - if (dotIndex > 0) - { - prefix = name.substring(0, dotIndex); - postfix = name.substring(dotIndex); - } - String recordName = prefix + " (" + recordId + ")" + postfix; - behaviourFilter.disableBehaviour(); - try - { - fileFolderService.rename(nodeRef, recordName); - } - catch (FileNotFoundException e) - { - throw new AlfrescoRuntimeException("Unable to make record, because rename failed.", e); - } - finally - { - behaviourFilter.enableBehaviour(); - } - - if (logger.isDebugEnabled()) - { - logger.debug("Rename " + name + " to " + recordName); - } - } - } - /** * Behaviour executed when a new item is added to a record folder. * @@ -853,6 +806,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // make the document a record makeRecord(nodeRef); + renameRecord(nodeRef); if (latestVersionRecord != null) { @@ -948,6 +902,7 @@ public class RecordServiceImpl extends BaseBehaviourBean // make record makeRecord(record); + renameRecord(record); // remove added copy assocs List recordAssocs = nodeService.getTargetAssocs(record, ContentModel.ASSOC_ORIGINAL); @@ -1082,6 +1037,7 @@ public class RecordServiceImpl extends BaseBehaviourBean { // make record makeRecord(record); + renameRecord(record); } return record; @@ -1129,6 +1085,11 @@ public class RecordServiceImpl extends BaseBehaviourBean // remove the owner ownableService.setOwner(document, OwnableService.NO_OWNER); + + if (TYPE_NON_ELECTRONIC_DOCUMENT.equals(nodeService.getType(document))) + { + renameRecord(document); + } } finally { @@ -1712,5 +1673,53 @@ public class RecordServiceImpl extends BaseBehaviourBean // can only unlink a record from a record folder throw new RecordLinkRuntimeException("Can only unlink a record from a record folder."); } - } + } + + /* + * @see org.alfresco.repo.content.ContentServicePolicies.OnContentUpdatePolicy#onContentUpdate(org.alfresco.service.cmr.repository.NodeRef, boolean) + */ + @Override + @Behaviour + ( + kind = BehaviourKind.CLASS, + type = "rma:record", + notificationFrequency = TRANSACTION_COMMIT + ) + public void onContentUpdate(NodeRef nodeRef, boolean newContent) + { + if (!nodeService.hasAspect(nodeRef, ContentModel.ASPECT_HIDDEN)) + { + renameRecord(nodeRef); + } + } + + private void renameRecord(NodeRef nodeRef) + { + // get the record id + String recordId = (String) nodeService.getProperty(nodeRef, PROP_IDENTIFIER); + + if (isNotBlank(recordId)) + { + // get the record name + String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + + // rename the record + int dotIndex = name.lastIndexOf('.'); + String prefix = name; + String postfix = ""; + if (dotIndex > 0) + { + prefix = name.substring(0, dotIndex); + postfix = name.substring(dotIndex); + } + String recordName = prefix + " (" + recordId + ")" + postfix; + + nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, recordName); + + if (logger.isDebugEnabled()) + { + logger.debug("Rename " + name + " to " + recordName); + } + } + } } From 5aa3721b911b28450a2afc45998d21059577bcc8 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Mon, 13 Mar 2017 01:01:33 +0000 Subject: [PATCH 14/19] RM-2396 (Upload record via WebDAV fails with org.alfresco.repo.security.permissions.AccessDeniedException) --- .../rm-service-context.xml | 31 ++++++++++++++++--- .../record/RecordServiceImpl.java | 28 +++++++++-------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml index e0548fd9db..b724fdb5b1 100644 --- a/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml +++ b/rm-community/rm-community-repo/config/alfresco/module/org_alfresco_module_rm/rm-service-context.xml @@ -1,8 +1,18 @@ - - - - + @@ -1060,8 +1070,21 @@ + + + + http://www.alfresco.org/model/security/1.0 + http://www.alfresco.org/model/system/1.0 + http://www.alfresco.org/model/workflow/1.0 + http://www.alfresco.org/model/application/1.0 + http://www.alfresco.org/model/datalist/1.0 + http://www.alfresco.org/model/dictionary/1.0 + http://www.alfresco.org/model/bpm/1.0 + http://www.alfresco.org/model/rendition/1.0 + + diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index f9c6b22383..73988eea1f 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -27,8 +27,6 @@ package org.alfresco.module.org_alfresco_module_rm.record; -import static com.google.common.collect.Lists.newArrayList; - import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.FIRST_EVENT; import static org.alfresco.repo.policy.Behaviour.NotificationFrequency.TRANSACTION_COMMIT; import static org.alfresco.repo.policy.annotation.BehaviourKind.ASSOCIATION; @@ -151,18 +149,22 @@ public class RecordServiceImpl extends BaseBehaviourBean }; /** always edit model URI's */ + private List alwaysEditURIs; + + /** + * @param alwaysEditURIs the alwaysEditURIs to set + */ + public void setAlwaysEditURIs(List alwaysEditURIs) + { + this.alwaysEditURIs = alwaysEditURIs; + } + + /** + * @return the alwaysEditURIs + */ protected List getAlwaysEditURIs() { - return newArrayList( - NamespaceService.SECURITY_MODEL_1_0_URI, - NamespaceService.SYSTEM_MODEL_1_0_URI, - NamespaceService.WORKFLOW_MODEL_1_0_URI, - NamespaceService.APP_MODEL_1_0_URI, - NamespaceService.DATALIST_MODEL_1_0_URI, - NamespaceService.DICTIONARY_MODEL_1_0_URI, - NamespaceService.BPM_MODEL_1_0_URI, - NamespaceService.RENDITION_MODEL_1_0_URI - ); + return this.alwaysEditURIs; } /** record model URI's */ @@ -1037,7 +1039,7 @@ public class RecordServiceImpl extends BaseBehaviourBean { // make record makeRecord(record); - renameRecord(record); + renameRecord(record); } return record; From d729a699228c2ddad33497fa32bc505d8fe4f563 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Mon, 13 Mar 2017 14:53:21 +0200 Subject: [PATCH 15/19] RM-3265 - fix merge error --- .../condition/MovableRecordFolderCapabilityCondition.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java index b2c887549b..41c0f4aba2 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/capability/declarative/condition/MovableRecordFolderCapabilityCondition.java @@ -47,6 +47,6 @@ public class MovableRecordFolderCapabilityCondition extends AbstractCapabilityCo { if (nodeService.hasAspect(nodeRef, ASPECT_GHOSTED) && dispositionService.isDisposableItemCutoff(nodeRef)) return true; - return !dispositionService.isDisposableItemCutoff(nodeRef) || recordFolderService.isRecordFolderClosed(nodeRef); + return !(dispositionService.isDisposableItemCutoff(nodeRef) || recordFolderService.isRecordFolderClosed(nodeRef)); } } From 793deafcbacfbd974052714d7f8909ea5af43743 Mon Sep 17 00:00:00 2001 From: Ana Bozianu Date: Mon, 13 Mar 2017 18:20:39 +0200 Subject: [PATCH 16/19] RM-3265 - added integration test for moving a closed folder --- .../recordfolder/MoveRecordFolderTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java index e0d62b9863..df34f5c96e 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/recordfolder/MoveRecordFolderTest.java @@ -510,6 +510,46 @@ public class MoveRecordFolderTest extends BaseRMTestCase } + /** + * Given a closed folder + * When we evaluate the move capability on it + * The access is denied + */ + public void testMoveClosedFolder() + { + final NodeRef destination = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create a record category + return filePlanService.createRecordCategory(filePlan, GUID.generate()); + } + }); + + final NodeRef testFolder = doTestInTransaction(new Test() + { + @Override + public NodeRef run() + { + // create folder + NodeRef testFolder = recordFolderService.createRecordFolder(rmContainer, GUID.generate()); + + // close folder + recordFolderService.closeRecordFolder(testFolder); + + return testFolder; + } + + @Override + public void test(NodeRef testFolder) throws Exception + { + Capability moveCapability = capabilityService.getCapability("MoveRecordFolder"); + assertEquals(AccessDecisionVoter.ACCESS_DENIED, moveCapability.evaluate(testFolder, destination)); + } + }); + } + private NodeRef createRecordCategory(boolean recordLevel) { NodeRef rc = filePlanService.createRecordCategory(filePlan, GUID.generate()); From 0e6fa39e5188c3844cd479647524d28dfa273ce1 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Wed, 15 Mar 2017 13:17:38 +0000 Subject: [PATCH 17/19] RM-4804_Transfer_Completed_Records --- .../transfer/TransferServiceImpl.java | 5 +- .../test/integration/issue/RM4804Test.java | 133 ++++++++++++++++++ 2 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4804Test.java diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java index 79aa6738e0..0939e2ed41 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/transfer/TransferServiceImpl.java @@ -222,15 +222,14 @@ public class TransferServiceImpl extends ServiceBaseImpl nodeRef, ASSOC_TRANSFERRED, ASSOC_TRANSFERRED); + // Set PDF indicator flag + setPDFIndicationFlag(transferNodeRef, nodeRef); } finally { transferType.enable(); } - // Set PDF indicator flag - setPDFIndicationFlag(transferNodeRef, nodeRef); - // Set the transferring indicator aspect nodeService.addAspect(nodeRef, ASPECT_TRANSFERRING, null); if (isRecordFolder(nodeRef)) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4804Test.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4804Test.java new file mode 100644 index 0000000000..0005ce388f --- /dev/null +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/integration/issue/RM4804Test.java @@ -0,0 +1,133 @@ +/* + * #%L + * Alfresco Records Management Module + * %% + * Copyright (C) 2005 - 2017 Alfresco Software Limited + * %% + * This file is part of the Alfresco software. + * - + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * - + * Alfresco is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * - + * Alfresco is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * - + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + * #L% + */ + +package org.alfresco.module.org_alfresco_module_rm.test.integration.issue; + +import java.io.InputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.model.ContentModel; +import org.alfresco.module.org_alfresco_module_rm.action.impl.CutOffAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferAction; +import org.alfresco.module.org_alfresco_module_rm.action.impl.TransferCompleteAction; +import org.alfresco.module.org_alfresco_module_rm.disposition.DispositionSchedule; +import org.alfresco.module.org_alfresco_module_rm.test.util.BaseRMTestCase; +import org.alfresco.module.org_alfresco_module_rm.test.util.CommonRMTestUtils; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.extensions.webscripts.GUID; + +/** + * Integration test for RM-4804 + * + * Completed records of type pdf can be transferred + * + * @author Ramona Popa + * @since 2.6 + */ +public class RM4804Test extends BaseRMTestCase +{ + /** + * Given a category with disposition schedule applied on folder with Cut Of and Transfer, a record folder and a file PDF document + * to folder, complete the record + * When execute disposition schedule steps + * Then the Transfer step is successfully finished + */ + @org.junit.Test + public void testTransferCompletedRecordOfTypePDF() throws Exception + { + doBehaviourDrivenTest(new BehaviourDrivenTest() + { + NodeRef recordCategory; + NodeRef recordFolder; + NodeRef record; + + public void given() + { + // category is created + recordCategory = filePlanService.createRecordCategory(filePlan, GUID.generate()); + + // create a disposition schedule for category, applied on folder + Map dsProps = new HashMap(3); + dsProps.put(PROP_DISPOSITION_AUTHORITY, CommonRMTestUtils.DEFAULT_DISPOSITION_AUTHORITY); + dsProps.put(PROP_DISPOSITION_INSTRUCTIONS, GUID.generate()); + dsProps.put(PROP_RECORD_LEVEL_DISPOSITION, false); + + DispositionSchedule dispositionSchedule = dispositionService.createDispositionSchedule(recordCategory, dsProps); + + // cutoff immediately + Map dispositionActionCutOff = new HashMap(3); + dispositionActionCutOff.put(PROP_DISPOSITION_ACTION_NAME, CutOffAction.NAME); + dispositionActionCutOff.put(PROP_DISPOSITION_DESCRIPTION, GUID.generate()); + dispositionActionCutOff.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); + + dispositionService.addDispositionActionDefinition(dispositionSchedule, dispositionActionCutOff); + + // transfer immediately + Map dispositionActionTransfer = new HashMap(4); + dispositionActionTransfer.put(PROP_DISPOSITION_ACTION_NAME, TransferAction.NAME); + dispositionActionTransfer.put(PROP_DISPOSITION_DESCRIPTION, GUID.generate()); + dispositionActionTransfer.put(PROP_DISPOSITION_PERIOD, CommonRMTestUtils.PERIOD_IMMEDIATELY); + dispositionActionTransfer.put(PROP_DISPOSITION_LOCATION, StringUtils.EMPTY); + + dispositionService.addDispositionActionDefinition(dispositionSchedule, dispositionActionTransfer); + + // add folder under category + recordFolder = recordFolderService.createRecordFolder(recordCategory, GUID.generate()); + + // add record of type PDF under folder + Map props = new HashMap(1); + props.put(ContentModel.PROP_TITLE, GUID.generate()); + InputStream inputStream = IOUtils.toInputStream(GUID.generate()); + record = utils.createRecord(recordFolder, GUID.generate(), props, MimetypeMap.MIMETYPE_PDF, inputStream); + + // complete the record + utils.completeRecord(record); + } + + public void when() + { + // cut off and transfer record + rmActionService.executeRecordsManagementAction(recordFolder, CutOffAction.NAME, null); + NodeRef transferFolder = (NodeRef) rmActionService.executeRecordsManagementAction(recordFolder, TransferAction.NAME) + .getValue(); + rmActionService.executeRecordsManagementAction(transferFolder, TransferCompleteAction.NAME); + } + + public void then() + { + // verify record is transferred + assertTrue(nodeService.hasAspect(record, ASPECT_TRANSFERRED)); + } + }); + } +} From 472debefac8fe2df9597dee3f06a20d8b2c37b27 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Wed, 15 Mar 2017 14:39:57 +0000 Subject: [PATCH 18/19] Fixed share port for local UI tests and also addressed review comment. --- .../org_alfresco_module_rm/record/RecordServiceImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java index 73988eea1f..cbea5ee6fe 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/module/org_alfresco_module_rm/record/RecordServiceImpl.java @@ -1695,6 +1695,11 @@ public class RecordServiceImpl extends BaseBehaviourBean } } + /** + * Appends the record identifier to the name of the record + * + * @param nodeRef The node reference of the record. + */ private void renameRecord(NodeRef nodeRef) { // get the record id From e60831a596036fcb143a39cbd4e04527befd3bf1 Mon Sep 17 00:00:00 2001 From: Tuna Aksoy Date: Wed, 15 Mar 2017 16:35:22 +0000 Subject: [PATCH 19/19] Excluded system test from the test suite. --- .../module/org_alfresco_module_rm/test/AllTestSuite.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java index 2207bd97a9..f1cb30820b 100644 --- a/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java +++ b/rm-community/rm-community-repo/test/java/org/alfresco/module/org_alfresco_module_rm/test/AllTestSuite.java @@ -52,6 +52,7 @@ import org.junit.runner.RunWith; "!.*RM2190Test", "!.*RM981SystemTest", "!.*RM3993Test", + "!.*RM4163Test", "!.*RecordsManagementEventServiceImplTest", "!.*RmRestApiTest", "!.*NotificationServiceHelperSystemTest",