/*
* 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;
}
}
}