diff --git a/config/alfresco/virtualization-context.xml b/config/alfresco/virtualization-context.xml index e1194d2524..ba15550d4a 100644 --- a/config/alfresco/virtualization-context.xml +++ b/config/alfresco/virtualization-context.xml @@ -200,8 +200,6 @@ - - diff --git a/source/java/org/alfresco/repo/virtual/VirtualContentModel.java b/source/java/org/alfresco/repo/virtual/VirtualContentModel.java index 701923a497..c5c8d685b0 100644 --- a/source/java/org/alfresco/repo/virtual/VirtualContentModel.java +++ b/source/java/org/alfresco/repo/virtual/VirtualContentModel.java @@ -38,4 +38,7 @@ public interface VirtualContentModel static final QName TYPE_VIRTUAL_FOLDER_TEMPLATE = QName.createQName(VIRTUAL_CONTENT_MODEL_1_0_URI, "virtualFolderTemplate"); + + static final QName PROP_ACTUAL_NODE_REF = QName.createQName(VIRTUAL_CONTENT_MODEL_1_0_URI, + "actualNodeRef"); } diff --git a/source/java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtension.java b/source/java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtension.java index f5e2526262..a9b0f86313 100644 --- a/source/java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtension.java +++ b/source/java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtension.java @@ -30,32 +30,35 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.alfresco.model.ContentModel; import org.alfresco.repo.preference.traitextender.PreferenceServiceExtension; import org.alfresco.repo.preference.traitextender.PreferenceServiceTrait; -import org.alfresco.repo.virtual.ActualEnvironment; import org.alfresco.repo.virtual.ref.GetActualNodeRefMethod; -import org.alfresco.repo.virtual.ref.GetParentReferenceMethod; import org.alfresco.repo.virtual.ref.Reference; -import org.alfresco.repo.virtual.store.VirtualStore; import org.alfresco.service.cmr.preference.PreferenceService; -import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.traitextender.SpringBeanExtension; +/** + * PreferenceServiceImpl extension used for manipulate favorites preferences + * that are set for virtual references. + * + * @author sdinuta + */ public class VirtualPreferenceServiceExtension extends - SpringBeanExtensionimplements PreferenceServiceExtension + SpringBeanExtension implements + PreferenceServiceExtension { + private static final String EMPTY_STRING = ""; private static final String DOCUMENTS_FAVOURITES_KEY = "org.alfresco.share.documents.favourites"; + private static final String FOLDERS_FAVOURITES_KEY = "org.alfresco.share.folders.favourites"; + private static final String CREATED_AT = ".createdAt"; private static final String EXT_DOCUMENTS_FAVOURITES = "org.alfresco.ext.documents.favourites."; - private VirtualStore virtualStore; - - private ActualEnvironment environment; + private static final String EXT_FOLDERS_FAVOURITES = "org.alfresco.ext.folders.favourites."; private PreferenceService preferenceService; @@ -64,35 +67,26 @@ public class VirtualPreferenceServiceExtension extends super(PreferenceServiceTrait.class); } - public ActualEnvironment getEnvironment() - { - return environment; - } - - public void setEnvironment(ActualEnvironment environment) - { - this.environment = environment; - } - - public PreferenceService getPreferenceService() - { - return preferenceService; - } - public void setPreferenceService(PreferenceService preferenceService) { this.preferenceService = preferenceService; } - public void setVirtualStore(VirtualStore virtualStore) - { - this.virtualStore = virtualStore; - } - - private String getExtDocumentPreferenceKey(Map preferences) + /** + * Obtains the org.alfresco.ext.documents.favourites.* or + * org.alfresco.ext.folders.favourites.* key used for setting favorites for + * documents and folders, or null if not favorites are targeted. + * + * @param preferences + * @return the org.alfresco.ext.documents.favourites.* or + * org.alfresco.ext.folders.favourites.* key used for setting + * favorites for documents and folders, or null if not favorites are + * targeted. + */ + private String getExtPreferenceKey(Map preferences) { String extKey = null; - if (!preferences.containsKey(DOCUMENTS_FAVOURITES_KEY)) + if (!preferences.containsKey(DOCUMENTS_FAVOURITES_KEY) && !preferences.containsKey(FOLDERS_FAVOURITES_KEY)) { return null; } @@ -101,7 +95,6 @@ public class VirtualPreferenceServiceExtension extends { return null; } - Iterator> iterator = entrySet.iterator(); if (!iterator.hasNext()) { @@ -111,31 +104,52 @@ public class VirtualPreferenceServiceExtension extends { Entry entry = iterator.next(); String key = entry.getKey(); - if (key.startsWith(EXT_DOCUMENTS_FAVOURITES)) + if (key.startsWith(EXT_DOCUMENTS_FAVOURITES) || key.startsWith(EXT_FOLDERS_FAVOURITES)) { extKey = key; break; } } - return extKey; } + /** + * If the favorites preferences are changed then for virtual references the + * actual nodeRef is added/removed from favorites preferences instead of + * virtual nodeRef. For non virtual entries or for preferences that are not + * related to favorites the original implementation from + * PreferenceServiceImpl is used. + */ @Override public void setPreferences(String userName, Map preferences) throws Throwable { final String comma = ","; - String extKey = getExtDocumentPreferenceKey(preferences); + String extKey = getExtPreferenceKey(preferences); if (extKey != null) { - String pattern = "^" + EXT_DOCUMENTS_FAVOURITES + "(\\S+)" + CREATED_AT + "$"; + String extFavKey; + String favKey; + if (extKey.startsWith(EXT_DOCUMENTS_FAVOURITES)) + // favorites for documents + { + extFavKey = EXT_DOCUMENTS_FAVOURITES; + favKey = DOCUMENTS_FAVOURITES_KEY; + } + else + // favorites for folders + { + extFavKey = EXT_FOLDERS_FAVOURITES; + favKey = FOLDERS_FAVOURITES_KEY; + } + + String pattern = "^" + extFavKey + "(\\S+)" + CREATED_AT + "$"; Pattern p = Pattern.compile(pattern); Matcher m = p.matcher(extKey); if (m.find()) { String documentNodeRefStr = m.group(1); - String favorites = (String) preferences.get(DOCUMENTS_FAVOURITES_KEY); + String favorites = (String) preferences.get(favKey); if (documentNodeRefStr != null && !documentNodeRefStr.isEmpty()) { NodeRef documentNodeRef = new NodeRef(documentNodeRefStr); @@ -145,65 +159,50 @@ public class VirtualPreferenceServiceExtension extends Reference reference = Reference.fromNodeRef(documentNodeRef); NodeRef actualNodeRef = reference.execute(new GetActualNodeRefMethod(null)); String actualNodeRefStr = actualNodeRef.toString(); - Reference parentVF = reference.execute(new GetParentReferenceMethod()); - NodeRef actualFolder = parentVF.execute(new GetActualNodeRefMethod(environment)); - Reference virtualizedRoot = virtualStore.virtualize(actualFolder); - String documentName = (String) environment.getProperty(documentNodeRef, - ContentModel.PROP_NAME); - List results = virtualStore.search(virtualizedRoot, - documentName, - true, - false, - true); - if (favorites.contains(documentNodeRefStr)) - { - for (Reference ref : results) - { - NodeRef nodeRef = ref.toNodeRef(); - String nodeRefStr = nodeRef.toString(); - if (!favorites.contains(nodeRefStr)) - { - if (favorites.isEmpty()) - { - favorites = nodeRefStr; - } - else - { - favorites = favorites + comma + nodeRefStr; - } + String actualExtPreference = extFavKey + actualNodeRefStr + CREATED_AT; + List elements = new ArrayList(Arrays.asList(favorites.split(comma))); + boolean elementsChanged = false; - } + if (favorites.contains(documentNodeRefStr)) + // add favorite + { + if (!preferences.containsKey(actualExtPreference)) + { + Serializable value = preferences.get(extKey); + preferences.put(actualExtPreference, + value); } + preferences.remove(extKey); + if (!favorites.contains(actualNodeRefStr)) { - favorites = favorites + comma + actualNodeRefStr; + favorites = favorites.replace(documentNodeRefStr, + actualNodeRefStr); } - preferences.put(DOCUMENTS_FAVOURITES_KEY, - favorites); - } - else - { - List elements = new ArrayList(Arrays.asList(favorites.split(comma))); - for (Reference ref : results) + else { - NodeRef nodeRef = ref.toNodeRef(); - String nodeRefStr = nodeRef.toString(); - if (elements.contains(nodeRefStr)) + if (elements.contains(documentNodeRefStr)) { - elements.remove(nodeRefStr); - String preferenceToClear = EXT_DOCUMENTS_FAVOURITES + nodeRefStr + CREATED_AT; - preferenceService.clearPreferences(userName, - preferenceToClear); + elements.remove(documentNodeRefStr); + elementsChanged = true; } } + } + else + // remove favorite + { if (elements.contains(actualNodeRefStr)) { elements.remove(actualNodeRefStr); - String preferenceToClear = EXT_DOCUMENTS_FAVOURITES + actualNodeRefStr + CREATED_AT; preferenceService.clearPreferences(userName, - preferenceToClear); + actualExtPreference); + elementsChanged = true; } - favorites = ""; + } + + if (elementsChanged) + { + favorites = EMPTY_STRING; for (String element : elements) { if (favorites.isEmpty()) @@ -215,83 +214,14 @@ public class VirtualPreferenceServiceExtension extends favorites = favorites + comma + element; } } - preferences.put(DOCUMENTS_FAVOURITES_KEY, - favorites); - } - } - else - { - ChildAssociationRef parentAssociation = environment.getPrimaryParent(documentNodeRef); - NodeRef parentNodeRef = parentAssociation.getParentRef(); - if (virtualStore.canVirtualize(parentNodeRef)) - { - Reference virtualizedRoot = virtualStore.virtualize(parentNodeRef); - String documentName = (String) environment.getProperty(documentNodeRef, - ContentModel.PROP_NAME); - List results = virtualStore.search(virtualizedRoot, - documentName, - true, - false, - true); - if (preferences.get(extKey) == null) - { - List elements = new ArrayList(Arrays.asList(favorites.split(comma))); - for (Reference ref : results) - { - NodeRef nodeRef = ref.toNodeRef(); - String nodeRefStr = nodeRef.toString(); - if (elements.contains(nodeRefStr)) - { - elements.remove(nodeRefStr); - String preferenceToClear = EXT_DOCUMENTS_FAVOURITES + nodeRefStr + CREATED_AT; - preferenceService.clearPreferences(userName, - preferenceToClear); - - } - } - favorites = ""; - for (String element : elements) - { - if (favorites.isEmpty()) - { - favorites = element; - } - else - { - favorites = favorites + comma + element; - } - } - preferences.put(DOCUMENTS_FAVOURITES_KEY, - favorites); - } - else - { - for (Reference ref : results) - { - NodeRef nodeRef = ref.toNodeRef(); - String nodeRefStr = nodeRef.toString(); - if (!favorites.contains(nodeRefStr)) - { - if (favorites.isEmpty()) - { - favorites = nodeRefStr; - } - else - { - favorites = favorites + comma + nodeRefStr; - } - } - } - preferences.put(DOCUMENTS_FAVOURITES_KEY, - favorites); - } } + preferences.put(favKey, + favorites); } } } } getTrait().setPreferences(userName, preferences); - } } diff --git a/source/java/org/alfresco/repo/virtual/store/VirtualStoreImpl.java b/source/java/org/alfresco/repo/virtual/store/VirtualStoreImpl.java index 4a5a14bc9b..1ef227b1a5 100644 --- a/source/java/org/alfresco/repo/virtual/store/VirtualStoreImpl.java +++ b/source/java/org/alfresco/repo/virtual/store/VirtualStoreImpl.java @@ -550,11 +550,11 @@ public class VirtualStoreImpl implements VirtualStore, VirtualFolderDefinitionRe else { vqConstraint = new NamePatternPropertyValueConstraint(new FilesFoldersConstraint(BasicConstraint.INSTANCE, - true, - true), - ContentModel.PROP_NAME, - namePattern, - environment.getNamespacePrefixResolver()); + true, + true), + ContentModel.PROP_NAME, + namePattern, + environment.getNamespacePrefixResolver()); } PagingResults queryNodes = query.perform(environment, vqConstraint, @@ -636,7 +636,10 @@ public class VirtualStoreImpl implements VirtualStore, VirtualFolderDefinitionRe else { NodeRef actual = reference.execute(new GetActualNodeRefMethod(environment)); - return environment.getProperties(actual); + Map properties = environment.getProperties(actual); + properties.put(VirtualContentModel.PROP_ACTUAL_NODE_REF, + actual.toString()); + return properties; } } @@ -657,7 +660,7 @@ public class VirtualStoreImpl implements VirtualStore, VirtualFolderDefinitionRe { filingRule = new NullFilingRule(environment); } - + FilingParameters filingParameters = new FilingParameters(parentReference, assocTypeQName, assocQName, diff --git a/source/test-java/org/alfresco/repo/virtual/VirtualizationIntegrationTestSuite.java b/source/test-java/org/alfresco/repo/virtual/VirtualizationIntegrationTestSuite.java index dc7feb1757..7c8b8270ac 100644 --- a/source/test-java/org/alfresco/repo/virtual/VirtualizationIntegrationTestSuite.java +++ b/source/test-java/org/alfresco/repo/virtual/VirtualizationIntegrationTestSuite.java @@ -28,6 +28,7 @@ import org.alfresco.repo.virtual.bundle.VirtualFileFolderServiceExtensionTest; import org.alfresco.repo.virtual.bundle.VirtualLockableAspectInterceptorExtensionTest; import org.alfresco.repo.virtual.bundle.VirtualNodeServiceExtensionTest; import org.alfresco.repo.virtual.bundle.VirtualPermissionServiceExtensionTest; +import org.alfresco.repo.virtual.bundle.VirtualPreferenceServiceExtensionTest; import org.alfresco.repo.virtual.bundle.VirtualRatingServiceExtensionTest; import org.alfresco.repo.virtual.bundle.VirtualVersionServiceExtensionTest; import org.alfresco.repo.virtual.config.NodeRefPathExpressionTest; @@ -49,6 +50,7 @@ public class VirtualizationIntegrationTestSuite extends TestSuite implements Vir { TestSuite suite = new TestSuite(); + suite.addTest(new JUnit4TestAdapter(VirtualPreferenceServiceExtensionTest.class)); suite.addTest(new JUnit4TestAdapter(VirtualLockableAspectInterceptorExtensionTest.class)); suite.addTest(new JUnit4TestAdapter(VirtualVersionServiceExtensionTest.class)); suite.addTest(new JUnit4TestAdapter(VirtualRatingServiceExtensionTest.class)); diff --git a/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtensionTest.java b/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtensionTest.java new file mode 100644 index 0000000000..d92a026b57 --- /dev/null +++ b/source/test-java/org/alfresco/repo/virtual/bundle/VirtualPreferenceServiceExtensionTest.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2005-2015 Alfresco Software Limited. + * + * This file is part of Alfresco + * + * 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/. + */ + +package org.alfresco.repo.virtual.bundle; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.TreeMap; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.virtual.VirtualizationIntegrationTest; +import org.alfresco.service.cmr.preference.PreferenceService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +public class VirtualPreferenceServiceExtensionTest extends VirtualizationIntegrationTest +{ + private static final String DOCUMENTS_FAVOURITES_KEY = "org.alfresco.share.documents.favourites"; + + private static final String EXT_DOCUMENTS_FAVOURITES = "org.alfresco.ext.documents.favourites."; + + private static final String FOLDERS_FAVOURITES_KEY = "org.alfresco.share.folders.favourites"; + + private static final String EXT_FOLDERS_FAVOURITES = "org.alfresco.ext.folders.favourites."; + + private static final String CREATED_AT = ".createdAt"; + + private PreferenceService preferenceService; + + @Override + protected void setUp() throws Exception + { + super.setUp(); + preferenceService = ctx.getBean("preferenceService", + PreferenceService.class); + } + + public void testSetFavoritesPreferencesForDocuments() throws Exception + { + NodeRef node2 = nodeService.getChildByName(virtualFolder1NodeRef, + ContentModel.ASSOC_CONTAINS, + "Node2"); + HashMap properties = new HashMap(); + properties.put(ContentModel.PROP_NAME, + "testfile.txt"); + QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, + QName.createValidLocalName("testfile.txt")); + + nodeService.createNode(node2, + ContentModel.ASSOC_CONTAINS, + assocQName, + ContentModel.TYPE_CONTENT, + properties); + NodeRef node2_1 = nodeService.getChildByName(node2, + ContentModel.ASSOC_CONTAINS, + "Node2_1"); + nodeService.createNode(node2_1, + ContentModel.ASSOC_CONTAINS, + assocQName, + ContentModel.TYPE_CONTENT, + properties); + + NodeRef testfile1 = nodeService.getChildByName(node2_1, + ContentModel.ASSOC_CONTAINS, + "testfile-1.txt"); + NodeRef physicalTestfile1 = nodeService.getChildByName(virtualFolder1NodeRef, + ContentModel.ASSOC_CONTAINS, + "testfile-1.txt"); + + // set preference to one document from one virtual folder and check if + // the actual nodeRef is present in + // org.alfresco.share.documents.favourites preference + Map preferences = new TreeMap(); + String key = EXT_DOCUMENTS_FAVOURITES + testfile1.toString() + CREATED_AT; + preferences.put(key, + "CREATED"); + preferences.put(DOCUMENTS_FAVOURITES_KEY, + testfile1.toString()); + preferenceService.setPreferences("admin", + preferences); + + String preference = (String) preferenceService.getPreference("admin", + DOCUMENTS_FAVOURITES_KEY); + assertFalse(preference.contains(testfile1.toString())); + assertTrue(preference.contains(physicalTestfile1.toString())); + assertNull((String) preferenceService.getPreference("admin", + EXT_DOCUMENTS_FAVOURITES + testfile1.toString() + + CREATED_AT)); + assertNotNull((String) preferenceService.getPreference("admin", + EXT_DOCUMENTS_FAVOURITES + physicalTestfile1.toString() + + CREATED_AT)); + + // remove favorite for a document from one virtual folder and check that + // the physical document is not favorite anymore + // and that the ext keys are removed + preferences = new TreeMap(); + key = EXT_DOCUMENTS_FAVOURITES + testfile1.toString() + CREATED_AT; + preferences.put(key, + null); + preferences.put(DOCUMENTS_FAVOURITES_KEY, + physicalTestfile1.toString()); + preferenceService.setPreferences("admin", + preferences); + + preference = (String) preferenceService.getPreference("admin", + DOCUMENTS_FAVOURITES_KEY); + assertTrue(preference.isEmpty()); + + assertNull((String) preferenceService.getPreference("admin", + EXT_DOCUMENTS_FAVOURITES + testfile1.toString() + + CREATED_AT)); + assertNull((String) preferenceService.getPreference("admin", + EXT_DOCUMENTS_FAVOURITES + physicalTestfile1.toString() + + CREATED_AT)); + } + + public void testSetFavoritesPreferencesForFolders() throws Exception + { + NodeRef physicalFolder = createFolder(testRootFolder.getNodeRef(), + "FOLDER").getChildRef(); + NodeRef virtualFolder = createVirtualizedFolder(testRootFolder.getNodeRef(), + VIRTUAL_FOLDER_2_NAME, + TEST_TEMPLATE_6_JSON_SYS_PATH); + NodeRef node1 = nodeService.getChildByName(virtualFolder, + ContentModel.ASSOC_CONTAINS, + "Node1"); + assertNotNull(node1); + + NodeRef physicalFolderInVirtualContext = nodeService.getChildByName(node1, + ContentModel.ASSOC_CONTAINS, + "FOLDER"); + assertNotNull(physicalFolderInVirtualContext); + + // set preference to one folder from one virtual folder and check if + // the actual nodeRef is present in + // org.alfresco.share.folders.favourites preference + Map preferences = new TreeMap(); + String key = EXT_FOLDERS_FAVOURITES + physicalFolderInVirtualContext.toString() + CREATED_AT; + preferences.put(key, + "CREATED"); + preferences.put(FOLDERS_FAVOURITES_KEY, + physicalFolderInVirtualContext.toString()); + preferenceService.setPreferences("admin", + preferences); + + String preference = (String) preferenceService.getPreference("admin", + FOLDERS_FAVOURITES_KEY); + assertFalse(preference.contains(physicalFolderInVirtualContext.toString())); + assertTrue(preference.contains(physicalFolder.toString())); + assertNull((String) preferenceService.getPreference("admin", + EXT_FOLDERS_FAVOURITES + + physicalFolderInVirtualContext.toString() + + CREATED_AT)); + assertNotNull((String) preferenceService.getPreference("admin", + EXT_FOLDERS_FAVOURITES + physicalFolder.toString() + + CREATED_AT)); + + // remove favorite for a folder from one virtual folder and check that + // the physical folder is not favorite anymore + // and that the ext keys are removed + preferences = new TreeMap(); + key = EXT_FOLDERS_FAVOURITES + physicalFolderInVirtualContext.toString() + CREATED_AT; + preferences.put(key, + null); + preferences.put(FOLDERS_FAVOURITES_KEY, + physicalFolder.toString()); + preferenceService.setPreferences("admin", + preferences); + + preference = (String) preferenceService.getPreference("admin", + FOLDERS_FAVOURITES_KEY); + assertTrue(preference.isEmpty()); + + assertNull((String) preferenceService.getPreference("admin", + EXT_FOLDERS_FAVOURITES + + physicalFolderInVirtualContext.toString() + + CREATED_AT)); + assertNull((String) preferenceService.getPreference("admin", + EXT_FOLDERS_FAVOURITES + physicalFolder.toString() + + CREATED_AT)); + } +} \ No newline at end of file