ItEr16S09RFComportamentoGraficoPlanificadorItEr15S12: Creating mutable tree model.

This commit is contained in:
Óscar González Fernández 2009-07-10 20:40:18 +02:00 committed by Javier Moran Rua
parent 0bc3242c09
commit a1e26c8370
3 changed files with 271 additions and 0 deletions

View file

@ -40,6 +40,11 @@
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-jdk1.5</artifactId>
</dependency>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,147 @@
package org.zkoss.ganttz.util;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import org.zkoss.zul.AbstractTreeModel;
import org.zkoss.zul.event.TreeDataEvent;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class MutableTreeModel<T> extends AbstractTreeModel {
private static class Node<T> {
private T value;
private List<Node<T>> children = new LinkedList<Node<T>>();
private Node<T> parentNode;
private Node(T value) {
this.value = value;
}
public void add(Node<T> node) {
node.parentNode = this;
children.add(node);
}
private void until(LinkedList<Integer> result, Node<T> parent) {
if (parent.equals(this)) {
return;
} else {
result.add(0, this.parentNode.getIndexOf(this));
this.parentNode.until(result, parent);
}
}
private int getIndexOf(Node<T> child) {
return children.indexOf(child);
}
public LinkedList<Integer> until(Node<T> parent) {
LinkedList<Integer> result = new LinkedList<Integer>();
until(result, parent);
return result;
}
}
private final Class<T> type;
private final Node<T> root;
private Map<T, Node<T>> nodesByDomainObject = new WeakHashMap<T, Node<T>>();
private static <T> Node<T> wrap(T object) {
return new Node<T>(object);
}
private Node<T> find(Object domainObject) {
Node<T> result = nodesByDomainObject.get(domainObject);
if (result == null)
throw new RuntimeException("not found " + domainObject);
return result;
}
private static <T> T unwrap(Node<T> node) {
return node == null ? null : node.value;
}
public static <T> MutableTreeModel<T> create(Class<T> type) {
return new MutableTreeModel<T>(type, new Node<T>(null));
}
public static <T> MutableTreeModel<T> create(Class<T> type, T root) {
return new MutableTreeModel<T>(type, wrap(root));
}
private MutableTreeModel(Class<T> type, Node<T> root) {
super(root);
if (type == null)
throw new IllegalArgumentException("type cannot be null");
nodesByDomainObject.put(unwrap(root), root);
this.type = type;
this.root = root;
}
@Override
public int[] getPath(Object parent, Object last) {
Node<T> parentNode = find(parent);
Node<T> lastNode = find(last);
List<Integer> path = lastNode.until(parentNode);
return asIntArray(path);
}
private int[] asIntArray(List<Integer> path) {
int[] result = new int[path.size()];
int i = 0;
for (Integer integer : path) {
result[i++] = integer;
}
return result;
}
@Override
public T getRoot() {
return unwrap(root);
}
@Override
public T getChild(Object parent, int index) {
Node<T> node = find(parent);
return unwrap(node.children.get(index));
}
@Override
public int getChildCount(Object parent) {
Node<T> node = find(parent);
return node.children.size();
}
@Override
public boolean isLeaf(Object object) {
Node<T> node = find(object);
return node.children.isEmpty();
}
public void addToRoot(T child) {
add(root, wrap(child));
}
private void add(Node<T> parent, Node<T> child) {
parent.add(child);
nodesByDomainObject.put(unwrap(child), child);
final int position = parent.children.size() - 1;
fireEvent(unwrap(parent), position, position,
TreeDataEvent.INTERVAL_ADDED);
}
public void add(T parent, T child) {
add(find(parent), wrap(child));
}
}

View file

@ -0,0 +1,119 @@
package org.zkoss.ganttz.util;
import static org.hamcrest.CoreMatchers.equalTo;
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.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.zkoss.zul.TreeModel;
import org.zkoss.zul.event.TreeDataEvent;
import org.zkoss.zul.event.TreeDataListener;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class MutableTreeModelTest {
public static class Prueba {
}
@Test
public void aMutableTreeModelIsAZkTreeModel() {
assertTrue(TreeModel.class.isAssignableFrom(MutableTreeModel.class));
}
@Test
public void aMutableTreeModelCanBeCreatedPassingType() {
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class);
assertNotNull(model);
assertNull(model.getRoot());
}
@Test
public void aMutableTreeModelCanBeCreatedPassingTypeAndRootObject() {
Prueba root = new Prueba();
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
root);
assertNotNull(model);
assertThat(model.getRoot(), equalTo(root));
}
@Test
public void childrenCanBeAdded() {
Prueba prueba = new Prueba();
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
prueba);
Prueba other = new Prueba();
model.add(model.getRoot(), other);
Prueba otherChild = new Prueba();
model.addToRoot(otherChild);
assertThat(model.getChildCount(model.getRoot()), equalTo(2));
assertThat(model.getChild(model.getRoot(), 0), equalTo(other));
assertThat(model.getChild(model.getRoot(), 1), equalTo(otherChild));
}
@Test
public void testLeaf() {
Prueba root = new Prueba();
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
root);
Prueba other = new Prueba();
model.add(model.getRoot(), other);
assertTrue(model.isLeaf(other));
assertFalse(model.isLeaf(root));
}
@Test
public void childAddedCanBeFoundUsingGetPath() {
Prueba root = new Prueba();
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class,
root);
Prueba child = new Prueba();
model.add(root, child);
int[] path = model.getPath(model.getRoot(), child);
assertThat(path.length, equalTo(1));
assertThat(path[0], equalTo(0));
}
@Test
public void addingTriggersEvent() {
MutableTreeModel<Prueba> model = MutableTreeModel.create(Prueba.class);
final ArrayList<TreeDataEvent> eventsFired = new ArrayList<TreeDataEvent>();
model.addTreeDataListener(new TreeDataListener() {
@Override
public void onChange(TreeDataEvent event) {
eventsFired.add(event);
}
});
Prueba child1 = new Prueba();
Prueba child2 = new Prueba();
Prueba granChildren1 = new Prueba();
model.add(model.getRoot(), child1);
checkIsValid(getLast(eventsFired), model.getRoot(), 0);
model.add(model.getRoot(), child2);
checkIsValid(getLast(eventsFired), model.getRoot(), 1);
model.add(child1, granChildren1);
checkIsValid(getLast(eventsFired), child1, 0);
assertThat(eventsFired.size(), equalTo(3));
}
private void checkIsValid(TreeDataEvent event, Prueba expectedParent,
int expectedPosition) {
assertEquals(expectedParent, event.getParent());
assertThat(event.getIndexFrom(), equalTo(expectedPosition));
assertThat(event.getIndexTo(), equalTo(expectedPosition));
assertThat(event.getType(), equalTo(TreeDataEvent.INTERVAL_ADDED));
}
private TreeDataEvent getLast(List<TreeDataEvent> list) {
return list.get(list.size() - 1);
}
}