package com.vaadin.v7.data.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Collection;
import com.vaadin.v7.data.Container;
import com.vaadin.v7.data.Container.Hierarchical;
import com.vaadin.v7.data.Container.Sortable;
import com.vaadin.v7.data.Item;
public abstract class AbstractHierarchicalContainerTestBase
extends AbstractContainerTestBase {
/**
* @param container
* The container to validate
* @param expectedFirstItemId
* Expected first item id
* @param expectedLastItemId
* Expected last item id
* @param itemIdInSet
* An item id that is in the container
* @param itemIdNotInSet
* An item id that is not in the container
* @param checkGetItemNull
* true if getItem() should return null for itemIdNotInSet, false
* to skip the check (container.containsId() is checked in any
* case)
* @param expectedSize
* Expected number of items in the container. Not related to
* hierarchy.
* @param expectedTraversalSize
* Expected number of items found when traversing from the roots
* down to all available nodes.
* @param expectedRootSize
* Expected number of root items
* @param rootsHaveChildren
* true if all roots have children, false otherwise (skips some
* asserts)
*/
protected void validateHierarchicalContainer(Hierarchical container,
Object expectedFirstItemId, Object expectedLastItemId,
Object itemIdInSet, Object itemIdNotInSet, boolean checkGetItemNull,
int expectedSize, int expectedRootSize, boolean rootsHaveChildren) {
validateContainer(container, expectedFirstItemId, expectedLastItemId,
itemIdInSet, itemIdNotInSet, checkGetItemNull, expectedSize);
// rootItemIds
Collection<?> rootIds = container.rootItemIds();
assertEquals(expectedRootSize, rootIds.size());
for (Object rootId : rootIds) {
// All roots must be in container
assertTrue(container.containsId(rootId));
// All roots must have no parent
assertNull(container.getParent(rootId));
// all roots must be roots
assertTrue(container.isRoot(rootId));
if (rootsHaveChildren) {
// all roots have children allowed in this case
assertTrue(container.areChildrenAllowed(rootId));
// all roots have children in this case
Collection<?> children = container.getChildren(rootId);
assertNotNull(rootId + " should have children", children);
assertTrue(rootId + " should have children",
(children.size() > 0));
// getParent
for (Object childId : children) {
assertEquals(container.getParent(childId), rootId);
}
}
}
// isRoot should return false for unknown items
assertFalse(container.isRoot(itemIdNotInSet));
// hasChildren should return false for unknown items
assertFalse(container.hasChildren(itemIdNotInSet));
// areChildrenAllowed should return false for unknown items
assertFalse(container.areChildrenAllowed(itemIdNotInSet));
// removeItem of unknown items should return false
assertFalse(container.removeItem(itemIdNotInSet));
assertEquals(expectedSize, countNodes(container));
validateHierarchy(container);
}
private int countNodes(Hierarchical container) {
int totalNodes = 0;
for (Object rootId : container.rootItemIds()) {
totalNodes += countNodes(container, rootId);
}
return totalNodes;
}
private int countNodes(Hierarchical container, Object itemId) {
int nodes = 1; // This
Collection<?> children = container.getChildren(itemId);
if (children != null) {
for (Object id : children) {
nodes += countNodes(container, id);
}
}
return nodes;
}
private void validateHierarchy(Hierarchical container) {
for (Object rootId : container.rootItemIds()) {
validateHierarchy(container, rootId, null);
}
}
private void validateHierarchy(Hierarchical container, Object itemId,
Object parentId) {
Collection<?> children = container.getChildren(itemId);
// getParent
assertEquals(container.getParent(itemId), parentId);
if (!container.areChildrenAllowed(itemId)) {
// If no children is allowed the item should have no children
assertFalse(container.hasChildren(itemId));
assertTrue(children == null || children.size() == 0);
return;
}
if (children != null) {
for (Object id : children) {
validateHierarchy(container, id, itemId);
}
}
}
protected void testHierarchicalContainer(Container.Hierarchical container) {
initializeContainer(container);
int packages = 21 + 3;
int expectedSize = sampleData.length + packages;
validateHierarchicalContainer(container, "com",
"org.vaadin.test.LastClass",
"com.vaadin.server.ApplicationResource", "blah", true,
expectedSize, 2, true);
}
protected void testHierarchicalSorting(Container.Hierarchical container) {
Container.Sortable sortable = (Sortable) container;
initializeContainer(container);
// Must be able to sort based on PROP1 and PROP2 for this test
assertTrue(sortable.getSortableContainerPropertyIds()
.contains(FULLY_QUALIFIED_NAME));
assertTrue(sortable.getSortableContainerPropertyIds()
.contains(REVERSE_FULLY_QUALIFIED_NAME));
sortable.sort(new Object[] { FULLY_QUALIFIED_NAME },
new boolean[] { true });
int packages = 21 + 3;
int expectedSize = sampleData.length + packages;
validateHierarchicalContainer(container, "com",
"org.vaadin.test.LastClass",
"com.vaadin.server.ApplicationResource", "blah", true,
expectedSize, 2, true);
sortable.sort(new Object[] { REVERSE_FULLY_QUALIFIED_NAME },
new boolean[] { true });
validateHierarchicalContainer(container,
"com.vaadin.server.ApplicationPortlet2",
"com.vaadin.data.util.ObjectProperty",
"com.vaadin.server.ApplicationResource", "blah", true,
expectedSize, 2, true);
}
protected void initializeContainer(Container.Hierarchical container) {
container.removeAllItems();
Object[] propertyIds = container.getContainerPropertyIds().toArray();
for (Object propertyId : propertyIds) {
container.removeContainerProperty(propertyId);
}
container.addContainerProperty(FULLY_QUALIFIED_NAME, String.class, "");
container.addContainerProperty(SIMPLE_NAME, String.class, "");
container.addContainerProperty(REVERSE_FULLY_QUALIFIED_NAME,
String.class, null);
container.addContainerProperty(ID_NUMBER, Integer.class, null);
for (int i = 0; i < sampleData.length; i++) {
String id = sampleData[i];
// Add path as parent
String paths[] = id.split("\\.");
String path = paths[0];
// Adds "com" and other items multiple times so should return null
// for all but the first time
if (container.addItem(path) != null) {
assertTrue(container.setChildrenAllowed(path, false));
Item item = container.getItem(path);
item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path);
item.getItemProperty(SIMPLE_NAME).setValue(getSimpleName(path));
item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME)
.setValue(reverse(path));
item.getItemProperty(ID_NUMBER).setValue(1);
}
for (int j = 1; j < paths.length; j++) {
String parent = path;
path = path + "." + paths[j];
// Adds "com" and other items multiple times so should return
// null for all but the first time
if (container.addItem(path) != null) {
assertTrue(container.setChildrenAllowed(path, false));
Item item = container.getItem(path);
item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(path);
item.getItemProperty(SIMPLE_NAME)
.setValue(getSimpleName(path));
item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME)
.setValue(reverse(path));
item.getItemProperty(ID_NUMBER).setValue(1);
}
assertTrue(container.setChildrenAllowed(parent, true));
assertTrue("Failed to set " + parent + " as parent for " + path,
container.setParent(path, parent));
}
Item item = container.getItem(id);
assertNotNull(item);
String parent = id.substring(0, id.lastIndexOf('.'));
assertTrue(container.setParent(id, parent));
item.getItemProperty(FULLY_QUALIFIED_NAME).setValue(sampleData[i]);
item.getItemProperty(SIMPLE_NAME)
.setValue(getSimpleName(sampleData[i]));
item.getItemProperty(REVERSE_FULLY_QUALIFIED_NAME)
.setValue(reverse(sampleData[i]));
item.getItemProperty(ID_NUMBER).setValue(i % 2);
}
}
protected void testRemoveHierarchicalWrapperSubtree(
Container.Hierarchical container) {
initializeContainer(container);
// remove root item
removeItemRecursively(container, "org");
int packages = 21 + 3 - 3;
int expectedSize = sampleData.length + packages - 1;
validateContainer(container, "com", "com.vaadin.util.SerializerHelper",
"com.vaadin.server.ApplicationResource", "blah", true,
expectedSize);
// rootItemIds
Collection<?> rootIds = container.rootItemIds();
assertEquals(1, rootIds.size());
}
private void removeItemRecursively(Container.Hierarchical container,
Object itemId) {
if (container instanceof ContainerHierarchicalWrapper) {
((ContainerHierarchicalWrapper) container)
.removeItemRecursively("org");
} else {
HierarchicalContainer.removeItemRecursively(container, itemId);
}
}
}