org.jgraph.graph.ParentMap Maven / Gradle / Ivy
Show all versions of ingeniasjgraphmod Show documentation
/*
* @(#)ParentMap.java 1.0 03-JUL-04
*
* Copyright (c) 2001-2004 Gaudenz Alder
*
*/
package org.jgraph.graph;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* An object that describes relations between childs and parents.
*
* @version 1.0 1/1/02
* @author Gaudenz Alder
*/
public class ParentMap implements Serializable {
/** Contents of the parent map. */
protected ArrayList entries = new ArrayList();
/**
* Set of changed changedNodes for the parent map. Includes childs and
* parents.
*/
protected Set changedNodes = new HashSet();
/** Maps parents to integers with the future number of childs. */
protected Map childCount = new Hashtable();
/**
* Constructs a ParentMap
object.
*/
public ParentMap() {
// empty
}
/**
* Constructs a ParentMap
object.
*/
public ParentMap(Object[] children, Object parent) {
addEntries(children, parent);
}
/**
* Returns a parent map that represents the insertion or removal of
* cells
in model
based on remove
.
* Unselected childs of selected nodes are moved to the first unselected
* parent of that node.
*
* Note: Consequently, cells "move up" one level when
* their parent is removed. Note: onlyUsePassedInCells can
* be used to indicate if only cells from the passed-in cell array are
* allowed parents. This is only used if remove is not true.
*/
public static ParentMap create(GraphModel m, Object[] c, boolean remove,
boolean onlyUsePassedInCells) {
Set cellSet = new HashSet();
for (int i = 0; i < c.length; i++) {
// Do not add null cells otherwise the while loop lower down runs
// in an infinite loop
if (c[i] != null) {
cellSet.add(c[i]);
}
}
ParentMap parentMap = new ParentMap();
for (int i = 0; i < c.length; i++) {
// Collect Parent Information
Object parent = m.getParent(c[i]);
if (parent != null
&& (!onlyUsePassedInCells || (!remove && cellSet
.contains(parent))))
parentMap.addEntry(c[i], (remove) ? null : parent);
if (remove) {
// Move Orphans to First Unselected Parent
while (cellSet.contains(parent)) {
// Make sure there are no nulls in the cell set or the
// while will get stuck in a loop
parent = m.getParent(parent);
}
for (int j = 0; j < m.getChildCount(c[i]); j++) {
Object child = m.getChild(c[i], j);
if (!cellSet.contains(child))
parentMap.addEntry(child, parent);
}
}
}
return parentMap;
}
/**
* Add a new entry for this child, parent pair to the parent map. The child
* and parent are added to the set of changed nodes. Note: The previous
* parent is changed on execution of this parent map and must be added by
* the GraphModel and reflected by the GraphChange.getChanged method. TODO:
* In general, the GraphModel should be in charge of computing the set of
* changed cells.
*/
public void addEntry(Object child, Object parent) {
if (child != null) {
entries.add(new Entry(child, parent));
// Update Changed Nodes
changedNodes.add(child);
if (parent != null)
changedNodes.add(parent);
}
}
/**
* Adds all child parent pairs using addEntry.
*/
public void addEntries(Object[] children, Object parent) {
for (int i = 0; i < children.length; i++)
addEntry(children[i], parent);
}
/**
* Returns the number of entries.
*/
public int size() {
return entries.size();
}
/**
* Returns an Iterator
for the entries in the map.
*/
public Iterator entries() {
return entries.iterator();
}
/**
* Returns a Set
for the nodes, childs and parents, in this
* parent map.
*/
public Set getChangedNodes() {
return changedNodes;
}
/**
* Creates a new parent map based on this parent map, where the child and
* parents are mapped using map
. If one the cells is not in
* map
, then the original cell is used instead.
*
*/
public ParentMap clone(Map map) {
ParentMap pm = new ParentMap();
Iterator it = entries();
while (it.hasNext()) {
Entry e = (Entry) it.next();
Object child = map.get(e.getChild());
Object parent = map.get(e.getParent());
if (child == null)
child = e.getChild();
if (parent == null)
parent = e.getParent();
if (child != null && parent != null)
pm.addEntry(child, parent);
}
return pm;
}
/**
* Object that represents the relation between a child an a parent.
*/
public class Entry implements Serializable {
/** Child and parent of the relation this entry describes. */
protected Object child, parent;
/**
* Constructs a new relation between child
and
* parent
.
*/
public Entry(Object child, Object parent) {
this.child = child;
this.parent = parent;
}
/**
* Returns the child of the relation.
*/
public Object getChild() {
return child;
}
/**
* Returns the parent of the relation.
*/
public Object getParent() {
return parent;
}
}
public String toString() {
String s = super.toString() + "\n";
Iterator it = entries();
while (it.hasNext()) {
Entry entry = (Entry) it.next();
s += " child=" + entry.getChild() + " parent=" + entry.getParent()
+ "\n";
}
return s;
}
}