/* * Copyright (C) 2011 eXo Platform SAS. * * This 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 2.1 of * the License, or (at your option) any later version. * * This software 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 this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.exoplatform.services.jcr.impl.dataflow.persistent; import org.exoplatform.commons.utils.QName; import org.exoplatform.services.jcr.JcrImplBaseTest; import org.exoplatform.services.jcr.access.AccessControlEntry; import org.exoplatform.services.jcr.access.AccessControlList; import org.exoplatform.services.jcr.config.RepositoryConfigurationException; import org.exoplatform.services.jcr.config.WorkspaceEntry; import org.exoplatform.services.jcr.core.WorkspaceContainerFacade; import org.exoplatform.services.jcr.dataflow.persistent.PersistedNodeData; import org.exoplatform.services.jcr.dataflow.persistent.WorkspaceStorageCache; import org.exoplatform.services.jcr.datamodel.ItemData; import org.exoplatform.services.jcr.datamodel.NodeData; import org.exoplatform.services.jcr.datamodel.QPath; import org.exoplatform.services.jcr.datamodel.QPathEntry; import org.exoplatform.services.jcr.impl.storage.SystemDataContainerHolder; import org.exoplatform.services.jcr.storage.WorkspaceStorageConnection; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jcr.RepositoryException; /** * @author <a href="mailto:skarpenko@exoplatform.com">Sergiy Karpenko</a> * @version $Id: exo-jboss-codetemplates.xml 34360 18.08.2011 skarpenko $ * */ public class TestCacheableWorksapceDataManagerBloomFilter extends JcrImplBaseTest { private MyWorkspaceDataContainer dataContainer; private CacheableWorkspaceDataManager mgr; public void setUp() throws Exception { super.setUp(); dataContainer = new MyWorkspaceDataContainer(); WorkspaceStorageCache cache = new MyWorkspaceStorageCache(); WorkspaceContainerFacade wsc = repository.getWorkspaceContainer("ws"); WorkspaceEntry wconf = (WorkspaceEntry)wsc.getComponent(WorkspaceEntry.class); mgr = new CacheableWorkspaceDataManager(wconf, dataContainer, cache, new SystemDataContainerHolder(dataContainer)); } protected void tearDown() throws Exception { dataContainer.clear(); dataContainer = null; mgr.clear(); mgr = null; super.tearDown(); } public void testGetItemWithACL() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("2", path = new QPath(new QPathEntry[]{new QPathEntry("", "2", 1, "2")}), "3", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(1, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemWithoutACL() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("3", path = new QPath(new QPathEntry[]{new QPathEntry("", "3", 1, "3")}), "4", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, null)); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(2, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentWithSingleOwner() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList("owner", null))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, null)); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(3, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentWithSinglePermission() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, null)); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(3, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentsWithCrossEmptyACL() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList("owner", null))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, null)); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(3, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentsWithCrossEmptyACL2() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList("owner", null))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, null)); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(3, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentsWithSameOwnerlessACL() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList("owner", null))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(2, dataContainer.getTotalCalls()); dataContainer.clear(); } public void testGetItemParentsWithSamePermissionlessACL() throws Exception { QPath path; dataContainer.add(new PersistedNodeData("4", path = new QPath(new QPathEntry[]{new QPathEntry("", "4", 1, "4")}), "5", 1, 1, null, null, new AccessControlList("owner", new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("3", path = QPath.makeChildPath(path, new QName("", "3"), 1, "3"), "4", 1, 1, null, null, new AccessControlList(null, new ArrayList<AccessControlEntry>()))); dataContainer.add(new PersistedNodeData("2", path = QPath.makeChildPath(path, new QName("", "2"), 1, "2"), "3", 1, 1, null, null, new AccessControlList("owner", null))); dataContainer.add(new PersistedNodeData("1", path = QPath.makeChildPath(path, new QName("", "1"), 1, "1"), "2", 1, 1, null, null, new AccessControlList("owner", null))); mgr.reloadFilters(); mgr.getItemData("1"); assertEquals(2, dataContainer.getTotalCalls()); dataContainer.clear(); } class MyWorkspaceDataContainer extends TestWorkspaceDataContainer { protected Map<String, NodeData> nodesById = new HashMap<String, NodeData>(); protected List<ACLHolder> holders = new ArrayList<ACLHolder>(); private int totalCalls; protected synchronized void incrementCalls() { totalCalls++; } public WorkspaceStorageConnection openConnection() throws RepositoryException { return new MyWorkspaceStorageConnection(this); } public WorkspaceStorageConnection openConnection(boolean readOnly) throws RepositoryException { return openConnection(); } public void clear() { nodesById.clear(); holders.clear(); totalCalls = 0; } public void add(NodeData node) { nodesById.put(node.getIdentifier(), node); AccessControlList acl = node.getACL(); if (acl != null) { ACLHolder holder = new ACLHolder(node.getIdentifier()); holder.setOwner(acl.hasOwner()); holder.setPermissions(acl.hasPermissions()); holders.add(holder); } } /** * @return the totalCalls */ public int getTotalCalls() { return totalCalls; } } class MyWorkspaceStorageConnection extends TestWorkspaceStorageConnection { private final MyWorkspaceDataContainer container; public MyWorkspaceStorageConnection(MyWorkspaceDataContainer myWorkspaceDataContainer) { container = myWorkspaceDataContainer; } /** * @see org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager#getItemData(java.lang.String) */ @Override public ItemData getItemData(String identifier) throws RepositoryException { container.incrementCalls(); return container.nodesById.get(identifier); } /** * @see org.exoplatform.services.jcr.impl.dataflow.persistent.CacheableWorkspaceDataManager#getACLHolders() */ @Override public List<ACLHolder> getACLHolders() throws RepositoryException { return container.holders; } } class MyWorkspaceStorageCache extends LinkedWorkspaceStorageCacheImpl { public MyWorkspaceStorageCache() throws RepositoryConfigurationException { super("", false, 0, 0, 30000, 30000, false, false, 0, false); } public boolean isEnabled() { return false; } } }