mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-22 15:12:38 +00:00 
			
		
		
		
	Merge branch 'release/V2.7.0.x' into 'release/V2.7'
Merge v2.7.0.x to v2.7 to include RM-6318 See merge request records-management/records-management!1010
This commit is contained in:
		| @@ -467,12 +467,18 @@ | |||||||
|       <property name="permissionService" ref="PermissionService" /> |       <property name="permissionService" ref="PermissionService" /> | ||||||
|       <property name="personService" ref="PersonService" /> |       <property name="personService" ref="PersonService" /> | ||||||
|       <property name="recordCategoryUtil" ref="RecordCategoryUtil" /> |       <property name="recordCategoryUtil" ref="RecordCategoryUtil" /> | ||||||
|  |       <property name="classificationReasonsUtil" ref="ClassificationReasonsUtil" /> | ||||||
|    </bean> |    </bean> | ||||||
|  |  | ||||||
|    <bean id="RecordCategoryUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordCategoryUtil"> |    <bean id="RecordCategoryUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RecordCategoryUtil"> | ||||||
|       <property name="nodeService" ref="NodeService"/> |       <property name="nodeService" ref="NodeService"/> | ||||||
|    </bean> |    </bean> | ||||||
|  |  | ||||||
|  |    <bean id="ClassificationReasonsUtil" class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil"> | ||||||
|  |       <property name="nodeService" ref="NodeService" /> | ||||||
|  |    </bean> | ||||||
|  |  | ||||||
|  |  | ||||||
|    <bean |    <bean | ||||||
|       id="webscript.org.alfresco.slingshot.rmsearch.rmsearchproperties.get" |       id="webscript.org.alfresco.slingshot.rmsearch.rmsearchproperties.get" | ||||||
|       class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RMSearchPropertiesGet" |       class="org.alfresco.module.org_alfresco_module_rm.script.slingshot.RMSearchPropertiesGet" | ||||||
|   | |||||||
| @@ -0,0 +1,86 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Records Management Module | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.module.org_alfresco_module_rm.script.slingshot; | ||||||
|  |  | ||||||
|  | import static org.alfresco.model.ContentModel.PROP_NAME; | ||||||
|  | import static org.alfresco.service.namespace.QName.createQName; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.alfresco.service.cmr.repository.StoreRef; | ||||||
|  | import org.alfresco.service.namespace.QName; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Method to replace the plain text classification reason id with the correct nodeRef during record search | ||||||
|  |  * @author Ross Gale | ||||||
|  |  * @since 2.7 | ||||||
|  |  */ | ||||||
|  | public class ClassificationReasonsUtil extends SearchUtil | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     public static final String CR_URI = "http://www.alfresco.org/model/securitymarks/1.0"; | ||||||
|  |     public static final QName CLASSIFICATION_REASONS_CONTAINER = createQName(CR_URI,"classificationReasonsContainer"); | ||||||
|  |     public static final QName PROP_CLASSIFICATION_REASON_CODE = createQName(CR_URI, "classificationReasonCode"); | ||||||
|  |     public static final String REASONS_KEY = "clf:classificationReasons:"; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Replace plain text reason id with nodeRef | ||||||
|  |      * @param searchQuery String e.g. clf:classificationReasons:1.4(a) | ||||||
|  |      * @return String e.g. clf:classificationReasons:5cc6d344-fa94-4370-9c81-d947b7e8f2ac | ||||||
|  |      */ | ||||||
|  |     public String replaceReasonWithNodeRef(String searchQuery) | ||||||
|  |     { | ||||||
|  |         List<String> queries = new ArrayList<>(Arrays.asList(searchQuery.split(" "))); | ||||||
|  |         StringBuilder stringBuilder = new StringBuilder(); | ||||||
|  |         for (String queryToEdit : queries) | ||||||
|  |         { | ||||||
|  |             if(queryToEdit.contains(REASONS_KEY)) | ||||||
|  |             { | ||||||
|  |                 for (String reasonId : retrieveAllNodeIds(getRootContainer(CLASSIFICATION_REASONS_CONTAINER))) | ||||||
|  |                 { | ||||||
|  |                     NodeRef reasonNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, reasonId); | ||||||
|  |                     Map<QName, Serializable> properties = nodeService.getProperties(reasonNodeRef); | ||||||
|  |                     if (queryToEdit.equals(REASONS_KEY + properties.get(PROP_CLASSIFICATION_REASON_CODE).toString()) || | ||||||
|  |                             queryToEdit.equals(REASONS_KEY +"\""+ properties.get(PROP_CLASSIFICATION_REASON_CODE).toString() + "\"")) | ||||||
|  |                     { | ||||||
|  |                         queryToEdit =  REASONS_KEY + properties.get(PROP_NAME).toString(); | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             stringBuilder.append(queryToEdit).append(" "); | ||||||
|  |         } | ||||||
|  |         return stringBuilder.toString(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -27,6 +27,8 @@ | |||||||
|  |  | ||||||
| package org.alfresco.module.org_alfresco_module_rm.script.slingshot; | package org.alfresco.module.org_alfresco_module_rm.script.slingshot; | ||||||
|  |  | ||||||
|  | import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.REASONS_KEY; | ||||||
|  |  | ||||||
| import java.io.Serializable; | import java.io.Serializable; | ||||||
| import java.io.UnsupportedEncodingException; | import java.io.UnsupportedEncodingException; | ||||||
| import java.net.URLEncoder; | import java.net.URLEncoder; | ||||||
| @@ -103,6 +105,9 @@ public class RMSearchGet extends DeclarativeWebScript | |||||||
|     /** Utility class for record categories */ |     /** Utility class for record categories */ | ||||||
|     private RecordCategoryUtil recordCategoryUtil; |     private RecordCategoryUtil recordCategoryUtil; | ||||||
|  |  | ||||||
|  |     /** Utility class for classification reasons (enterprise only) */ | ||||||
|  |     private ClassificationReasonsUtil classificationReasonsUtil; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param recordsManagementSearchService    records management search service |      * @param recordsManagementSearchService    records management search service | ||||||
|      */ |      */ | ||||||
| @@ -159,6 +164,11 @@ public class RMSearchGet extends DeclarativeWebScript | |||||||
|         this.recordCategoryUtil = recordCategoryUtil; |         this.recordCategoryUtil = recordCategoryUtil; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public void setClassificationReasonsUtil(ClassificationReasonsUtil classificationReasonsUtil) | ||||||
|  |     { | ||||||
|  |         this.classificationReasonsUtil = classificationReasonsUtil; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @param personService person service |      * @param personService person service | ||||||
|      */ |      */ | ||||||
| @@ -198,6 +208,12 @@ public class RMSearchGet extends DeclarativeWebScript | |||||||
|             String filters = req.getParameter(PARAM_FILTERS); |             String filters = req.getParameter(PARAM_FILTERS); | ||||||
|             // TODO this is optional |             // TODO this is optional | ||||||
|  |  | ||||||
|  |             //Replace any plain text reason ids with the appropriate node reference | ||||||
|  |             if(query.contains(REASONS_KEY)) | ||||||
|  |             { | ||||||
|  |                 query = classificationReasonsUtil.replaceReasonWithNodeRef(query); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             // Convert into a rm search parameter object |             // Convert into a rm search parameter object | ||||||
|             RecordsManagementSearchParameters searchParameters = |             RecordsManagementSearchParameters searchParameters = | ||||||
|                     SavedSearchDetailsCompatibility.createSearchParameters(filters, new String[]{",", "/"}, sortby, namespaceService); |                     SavedSearchDetailsCompatibility.createSearchParameters(filters, new String[]{",", "/"}, sortby, namespaceService); | ||||||
|   | |||||||
| @@ -0,0 +1,103 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Records Management Module | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.module.org_alfresco_module_rm.script.slingshot; | ||||||
|  |  | ||||||
|  | import static org.alfresco.model.ContentModel.ASSOC_CHILDREN; | ||||||
|  | import static org.alfresco.model.ContentModel.TYPE_CONTAINER; | ||||||
|  | import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Set; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
|  | import org.alfresco.error.AlfrescoRuntimeException; | ||||||
|  | import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeService; | ||||||
|  | import org.alfresco.service.namespace.QName; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Parent class for records search utilities | ||||||
|  |  * | ||||||
|  |  * @author Ross Gale | ||||||
|  |  * @since 2.7 | ||||||
|  |  */ | ||||||
|  | public class SearchUtil | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Node service | ||||||
|  |      */ | ||||||
|  |     protected NodeService nodeService; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Setter for node service | ||||||
|  |      * | ||||||
|  |      * @param nodeService Node service | ||||||
|  |      */ | ||||||
|  |     public void setNodeService(NodeService nodeService) | ||||||
|  |     { | ||||||
|  |         this.nodeService = nodeService; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Use a container node ref and return the nodeIds of the contents | ||||||
|  |      * | ||||||
|  |      * @param nodeRef container | ||||||
|  |      * @return list of nodeIds | ||||||
|  |      */ | ||||||
|  |     protected Set<String> retrieveAllNodeIds(NodeRef nodeRef) | ||||||
|  |     { | ||||||
|  |         List<ChildAssociationRef> childAssocRefs = nodeService.getChildAssocs(nodeRef); | ||||||
|  |         return childAssocRefs.stream().map(assoc -> assoc.getChildRef().getId()).collect(Collectors.toSet()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Helper method to get the classification reason root container. | ||||||
|  |      * The method creates the container if it doesn't already exist. | ||||||
|  |      * | ||||||
|  |      * @return reference to the classification reason root container | ||||||
|  |      */ | ||||||
|  |     protected NodeRef getRootContainer(QName container) | ||||||
|  |     { | ||||||
|  |         NodeRef rootNodeRef = nodeService.getRootNode(STORE_REF_WORKSPACE_SPACESSTORE); | ||||||
|  |         List<ChildAssociationRef> assocRefs = nodeService.getChildAssocs(rootNodeRef, ASSOC_CHILDREN, container); | ||||||
|  |  | ||||||
|  |         if (assocRefs.isEmpty()) | ||||||
|  |         { | ||||||
|  |             return nodeService.createNode(rootNodeRef, ASSOC_CHILDREN, container, TYPE_CONTAINER).getChildRef(); | ||||||
|  |         } | ||||||
|  |         else if (assocRefs.size() != 1) | ||||||
|  |         { | ||||||
|  |             throw new AlfrescoRuntimeException("Only one container is allowed."); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             return assocRefs.iterator().next().getChildRef(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,128 @@ | |||||||
|  | /* | ||||||
|  |  * #%L | ||||||
|  |  * Alfresco Records Management Module | ||||||
|  |  * %% | ||||||
|  |  * Copyright (C) 2005 - 2018 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 <http://www.gnu.org/licenses/>. | ||||||
|  |  * #L% | ||||||
|  |  */ | ||||||
|  | package org.alfresco.module.org_alfresco_module_rm.script.slingshot; | ||||||
|  |  | ||||||
|  | import static org.alfresco.model.ContentModel.ASSOC_CHILDREN; | ||||||
|  | import static org.alfresco.model.ContentModel.PROP_NAME; | ||||||
|  | import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.CLASSIFICATION_REASONS_CONTAINER; | ||||||
|  | import static org.alfresco.module.org_alfresco_module_rm.script.slingshot.ClassificationReasonsUtil.PROP_CLASSIFICATION_REASON_CODE; | ||||||
|  | import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE; | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | import static org.mockito.Mockito.when; | ||||||
|  |  | ||||||
|  | import java.io.Serializable; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.Map; | ||||||
|  |  | ||||||
|  | import org.alfresco.service.cmr.repository.ChildAssociationRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeRef; | ||||||
|  | import org.alfresco.service.cmr.repository.NodeService; | ||||||
|  | import org.alfresco.service.namespace.QName; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.mockito.InjectMocks; | ||||||
|  | import org.mockito.Mock; | ||||||
|  | import org.mockito.MockitoAnnotations; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * @author Ross Gale | ||||||
|  |  * @since 2.7 | ||||||
|  |  */ | ||||||
|  | public class ClassificationReasonsUtilUnitTest | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private NodeService nodeService; | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private ChildAssociationRef childAssociationRef; | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private ChildAssociationRef reason; | ||||||
|  |  | ||||||
|  |     @Mock | ||||||
|  |     private Map<QName, Serializable> properties; | ||||||
|  |  | ||||||
|  |     @InjectMocks | ||||||
|  |     private ClassificationReasonsUtil classificationReasonsUtil; | ||||||
|  |  | ||||||
|  |     private NodeRef childNodeRef; | ||||||
|  |  | ||||||
|  |     @Before | ||||||
|  |     public void setUp() | ||||||
|  |     { | ||||||
|  |         MockitoAnnotations.initMocks(this); | ||||||
|  |         NodeRef rootNodeRef = new NodeRef("workspace://SpacesStore/rootNodeRef"); | ||||||
|  |         NodeRef containerNodeRef = new NodeRef("workspace://SpacesStore/containerNodeRef"); | ||||||
|  |         childNodeRef = new NodeRef("workspace://SpacesStore/childNodeRef"); | ||||||
|  |         List<ChildAssociationRef> assocRefs = new ArrayList<>(); | ||||||
|  |         List<ChildAssociationRef> childAssocRefs = new ArrayList<>(); | ||||||
|  |         assocRefs.add(childAssociationRef); | ||||||
|  |         childAssocRefs.add(reason); | ||||||
|  |         when(reason.getChildRef()).thenReturn(childNodeRef); | ||||||
|  |         when(nodeService.getRootNode(STORE_REF_WORKSPACE_SPACESSTORE)).thenReturn(rootNodeRef); | ||||||
|  |         when(nodeService.getChildAssocs(rootNodeRef, ASSOC_CHILDREN, CLASSIFICATION_REASONS_CONTAINER)).thenReturn(assocRefs); | ||||||
|  |         when(childAssociationRef.getChildRef()).thenReturn(containerNodeRef); | ||||||
|  |         when(nodeService.getChildAssocs(containerNodeRef)).thenReturn(childAssocRefs); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check no modifications are made to non matching parts of the query string | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     public void testNoChangeMadeToStringIfKeyNotFound() | ||||||
|  |     { | ||||||
|  |         String stringToTest = "noChangeMadeToString"; | ||||||
|  |         assertEquals("Change made to string",stringToTest, classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check no modifications made if the plain text parameter doesn't have a stored match | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     public void testNoChangeMadeToStringIfMatchNotFound() | ||||||
|  |     { | ||||||
|  |         when(nodeService.getProperties(childNodeRef)).thenReturn(properties); | ||||||
|  |         when(properties.get(PROP_CLASSIFICATION_REASON_CODE)).thenReturn("not a match!"); | ||||||
|  |         String stringToTest = "clf:classificationReasons:noChangeMadeToString"; | ||||||
|  |         assertEquals("Change made to string", stringToTest, classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Check the query is updated correctly when a match is found | ||||||
|  |      */ | ||||||
|  |     @Test | ||||||
|  |     public void testChangeMadeToStringIfMatchFound() | ||||||
|  |     { | ||||||
|  |         when(nodeService.getProperties(childNodeRef)).thenReturn(properties); | ||||||
|  |         when(properties.get(PROP_CLASSIFICATION_REASON_CODE)).thenReturn("stringToChange"); | ||||||
|  |         when(properties.get(PROP_NAME)).thenReturn("newString"); | ||||||
|  |         String stringToTest = "clf:classificationReasons:stringToChange"; | ||||||
|  |         assertEquals("No change made to string", "clf:classificationReasons:newString", classificationReasonsUtil.replaceReasonWithNodeRef(stringToTest).trim()); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user