
it.unitn.disi.smatch.data.trees.BaseNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of s-match Show documentation
Show all versions of s-match Show documentation
A version of S-Match semantic matching framework for Open Data
The newest version!
package it.unitn.disi.smatch.data.trees;
import it.unitn.disi.smatch.data.matrices.IndexedObject;
import javax.swing.event.EventListenerList;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import java.util.*;
/**
* Base node class.
*
* @author Aliaksandr Autayeu
*/
@SuppressWarnings({"unchecked"})
public class BaseNode extends IndexedObject implements IBaseNode, IBaseNodeData {
protected E parent;
protected ArrayList children;
protected ArrayList ancestors;
protected int ancestorCount;
protected ArrayList descendants;
protected int descendantCount;
protected EventListenerList listenerList;
// id is needed to store cNodeFormulas correctly.
// cNodeFormula is made of cLabFormulas, each of which refers to tokens and tokens should have unique id
// within a context. This is achieved by using node id + token id for each token
protected String id;
protected String name;
protected Object userObject;
// node counter to set unique node id during creation
protected static long countNode = 0;
// iterator which iterates over all parent nodes
private final class Ancestors implements Iterator {
private E current;
public Ancestors(E start) {
if (null == start) {
throw new IllegalArgumentException("argument is null");
}
this.current = start;
}
public boolean hasNext() {
return current.hasParent();
}
public E next() {
current = (E) current.getParent();
return current;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
class BreadthFirstSearch implements Iterator {
private Deque queue;
public BreadthFirstSearch(E start) {
if (null == start) {
throw new IllegalArgumentException("argument is null");
}
queue = new ArrayDeque();
queue.addFirst(start);
next();
}
public boolean hasNext() {
return !queue.isEmpty();
}
public E next() {
E current = queue.removeFirst();
for (Iterator i = current.getChildren(); i.hasNext();) {
queue.add(i.next());
}
return current;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public static final Comparator NODE_NAME_COMPARATOR = new Comparator() {
public int compare(IBaseNode e1, IBaseNode e2) {
return e1.getNodeData().getName().compareTo(e2.getNodeData().getName());
}
};
public BaseNode() {
parent = null;
children = null;
ancestors = null;
ancestorCount = -1;
descendants = null;
descendantCount = -1;
listenerList = null;
// need to set node id to keep track of acols in c@node formulas
// synchronized to make counts unique within JVM and decrease the chance of creating the same id
synchronized (Node.class) {
id = "n" + countNode + "_" + ((System.currentTimeMillis() / 1000) % (365 * 24 * 3600));
countNode++;
}
name = "";
}
/**
* Constructor class which sets the node name.
*
* @param name the name of the node
*/
public BaseNode(String name) {
this();
this.name = name;
}
public E getChildAt(int index) {
if (children == null) {
throw new ArrayIndexOutOfBoundsException("node has no children");
}
return children.get(index);
}
public int getChildCount() {
if (children == null) {
return 0;
} else {
return children.size();
}
}
public int getChildIndex(E child) {
if (null == child) {
throw new IllegalArgumentException("argument is null");
}
if (!isNodeChild(child)) {
return -1;
}
return children.indexOf(child);
}
public Iterator getChildren() {
if (null == children) {
return Collections.emptyList().iterator();
} else {
return children.iterator();
}
}
public List getChildrenList() {
if (null != children) {
return Collections.unmodifiableList(children);
} else {
return Collections.emptyList();
}
}
public E createChild() {
E child = (E) new BaseNode();
addChild(child);
return child;
}
public E createChild(String name) {
E child = (E) new BaseNode(name);
addChild(child);
return child;
}
public void addChild(E child) {
addChild(getChildCount(), child);
}
public void addChild(int index, E child) {
if (null == child) {
throw new IllegalArgumentException("new child is null");
} else if (isNodeAncestor(child)) {
throw new IllegalArgumentException("new child is an ancestor");
}
IBaseNode oldParent = child.getParent();
if (null != oldParent) {
oldParent.removeChild(child);
}
child.setParent(this);
if (null == children) {
children = new ArrayList();
}
children.add(index, child);
fireTreeStructureChanged((E) this);
}
public void removeChild(int index) {
E child = getChildAt(index);
children.remove(index);
fireTreeStructureChanged((E) this);
child.setParent(null);
}
public void removeChild(E child) {
if (null == child) {
throw new IllegalArgumentException("argument is null");
}
if (isNodeChild(child)) {
removeChild(getChildIndex(child));
}
}
public E getParent() {
return parent;
}
public void setParent(E newParent) {
removeFromParent();
parent = newParent;
}
public boolean hasParent() {
return null != parent;
}
public void removeFromParent() {
if (null != parent) {
parent.removeChild(this);
parent = null;
}
}
public boolean isLeaf() {
return 0 == getChildCount();
}
public int getAncestorCount() {
if (-1 == ancestorCount) {
if (null == ancestors) {
ancestorCount = 0;
if (null != parent) {
ancestorCount = parent.getAncestorCount() + 1;
}
} else {
ancestorCount = ancestors.size();
}
}
return ancestorCount;
}
public Iterator getAncestors() {
return new Ancestors((E) this);
}
public List getAncestorsList() {
if (null == ancestors) {
ancestors = new ArrayList(getAncestorCount());
if (null != parent) {
ancestors.add(parent);
ancestors.addAll(parent.getAncestorsList());
}
}
return Collections.unmodifiableList(ancestors);
}
public int getLevel() {
return getAncestorCount();
}
public int getDescendantCount() {
if (-1 == descendantCount) {
if (null == descendants) {
descendantCount = 0;
for (Iterator i = getDescendants(); i.hasNext();) {
i.next();
descendantCount++;
}
} else {
descendantCount = descendants.size();
}
}
return descendantCount;
}
public Iterator getDescendants() {
return new BreadthFirstSearch((E) this);
}
public List getDescendantsList() {
if (null == descendants) {
descendants = new ArrayList(getChildCount());
if (null != children) {
descendants.addAll(children);
for (IBaseNode child : children) {
descendants.addAll(child.getDescendantsList());
}
descendants.trimToSize();
}
}
return Collections.unmodifiableList(descendants);
}
public Iterator getSubtree() {
return new StartIterator((E) this, getDescendants());
}
public I getNodeData() {
return (I) this;
}
private boolean isNodeAncestor(E anotherNode) {
if (null == anotherNode) {
return false;
}
E ancestor = (E) this;
do {
if (ancestor == anotherNode) {
return true;
}
} while ((ancestor = (E) ancestor.getParent()) != null);
return false;
}
private boolean isNodeChild(E node) {
if (null == node) {
return false;
} else {
if (getChildCount() == 0) {
return false;
} else {
return (node.getParent() == this && -1 < children.indexOf(node));
}
}
}
public String getName() {
return name;
}
public void setName(String newName) {
name = newName;
}
public String getId() {
return id;
}
public void setId(String newId) {
id = newId;
}
public Object getUserObject() {
return userObject;
}
public void setUserObject(Object object) {
userObject = object;
}
public String toString() {
return name;
}
public int getIndex(TreeNode node) {
if (node instanceof IBaseNode) {
return getChildIndex((E) node);
} else {
return -1;
}
}
public boolean getAllowsChildren() {
return true;
}
public Enumeration children() {
return Collections.enumeration(children);
}
public void insert(MutableTreeNode child, int index) {
if (child instanceof IBaseNode) {
addChild(index, (E) child);
}
}
public void remove(int index) {
removeChild(index);
}
public void remove(MutableTreeNode node) {
if (node instanceof IBaseNode) {
removeChild((E) node);
}
}
public void setParent(MutableTreeNode newParent) {
if (newParent instanceof IBaseNode) {
setParent(newParent);
}
}
public void addTreeStructureChangedListener(IBaseTreeStructureChangedListener l) {
if (null == listenerList) {
listenerList = new EventListenerList();
}
listenerList.add(IBaseTreeStructureChangedListener.class, l);
}
public void removeTreeStructureChangedListener(IBaseTreeStructureChangedListener l) {
if (null != listenerList) {
listenerList.remove(IBaseTreeStructureChangedListener.class, l);
}
}
public void fireTreeStructureChanged(E node) {
descendants = null;
if (null != listenerList) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i + 1] instanceof IBaseTreeStructureChangedListener) {
// Lazily create the event:
((IBaseTreeStructureChangedListener) listeners[i + 1]).treeStructureChanged(node);
}
}
}
if (null != parent) {
parent.fireTreeStructureChanged(node);
}
}
public void trim() {
if (null != children) {
children.trimToSize();
for (IBaseNode child : children) {
if (child instanceof BaseNode) {
((BaseNode) child).trim();
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy