information-system-model/src/main/java/org/gcube/informationsystem/tree/Tree.java

124 lines
3.0 KiB
Java
Raw Normal View History

2023-02-03 19:13:04 +01:00
package org.gcube.informationsystem.tree;
2023-02-03 17:53:42 +01:00
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* @author Luca Frosini (ISTI - CNR)
*/
2023-02-03 19:13:04 +01:00
public class Tree<T> {
2023-02-03 17:53:42 +01:00
private boolean allowMultipleInheritance;
2023-10-27 14:50:16 +02:00
private Node<T> rootNode;
2023-02-06 11:07:52 +01:00
private NodeInformation<T> ni;
2023-02-03 19:13:04 +01:00
private Map<String, Node<T>> locate;
2023-02-03 17:53:42 +01:00
2023-10-27 14:50:16 +02:00
public Tree() {
2023-02-06 11:07:52 +01:00
this.allowMultipleInheritance = true;
2023-02-03 17:53:42 +01:00
this.locate = new HashMap<>();
2023-10-27 14:50:16 +02:00
}
public Tree(NodeInformation<T> ni) {
this();
setNodeInformation(ni);
}
public Tree(T root, NodeInformation<T> ni) {
this(ni);
setRoot(root);
}
/**
* Set the NodeInformation if and only if it was not previously set.
* Otherwise this function has no effect.
* @param ni the NodeInformation to set
*/
public void setNodeInformation(NodeInformation<T> ni) {
if(this.ni==null) {
this.ni = ni;
}
}
/**
* Set the root if and only if it was not previously set.
* Otherwise this function has no effect.
* This function raises a RuntimeException is the
* NodeInformation was not previously set.
* @param root the root to set
*/
public void setRoot(T root) throws RuntimeException {
if(this.ni==null) {
throw new RuntimeException("You must set the NodeInformation instance first");
}
if(this.rootNode==null) {
this.rootNode = new Node<>(root);
this.rootNode.setTree(this);
String identifier = ni.getIdentifier(root);
this.locate.put(identifier, rootNode);
}
2023-02-03 17:53:42 +01:00
}
public void setAllowMultipleInheritance(boolean allowMultipleInheritance) {
this.allowMultipleInheritance = allowMultipleInheritance;
}
2023-02-06 11:07:52 +01:00
public NodeInformation<T> getNodeInformation() {
return ni;
2023-02-03 17:53:42 +01:00
}
2023-02-03 19:13:04 +01:00
public Node<T> addNode(T t) {
2023-02-06 11:07:52 +01:00
String identifier = ni.getIdentifier(t);
2023-02-03 17:53:42 +01:00
if(locate.containsKey(identifier)) {
2023-02-06 11:07:52 +01:00
// has been already added
2023-02-03 17:53:42 +01:00
return locate.get(identifier);
}
2023-02-03 19:13:04 +01:00
Node<T> node = new Node<>(t);
2023-02-06 18:52:08 +01:00
node.setTree(this);
2023-02-03 17:53:42 +01:00
2023-10-27 14:50:16 +02:00
Set<String> parentIdentifiers = ni.getParentIdentifiers(rootNode!= null ? rootNode.getNodeElement() : null, t);
if(parentIdentifiers==null || parentIdentifiers.size()==0) {
if(this.rootNode==null) {
this.rootNode = node;
}else {
throw new RuntimeException("A Tree cannot have two root. " + t.toString() + " has not parent.");
2023-02-03 17:53:42 +01:00
}
2023-10-27 14:50:16 +02:00
} else {
for(String parentIdentifier : parentIdentifiers) {
Node<T> parentNode = locate.get(parentIdentifier);
if(parentNode==null) {
throw new RuntimeException("I can find parent for " + identifier + ". Missing parent is " + parentIdentifier);
}
parentNode.addChild(node);
if(!allowMultipleInheritance) {
break;
}
2023-02-03 17:53:42 +01:00
}
}
this.locate.put(identifier, node);
return node;
}
2023-10-27 14:50:16 +02:00
public Node<T> getRootNode() {
return rootNode;
2023-02-03 17:53:42 +01:00
}
@Override
public String toString() {
2023-10-27 14:50:16 +02:00
return rootNode.toString();
2023-02-03 17:53:42 +01:00
}
2023-02-03 19:13:04 +01:00
public void elaborate(NodeElaborator<T> nodeElaborator) throws Exception {
2023-10-27 14:50:16 +02:00
rootNode.elaborate(nodeElaborator);
2023-02-03 17:53:42 +01:00
}
2023-10-27 18:11:58 +02:00
public Node<T> getNodeByIdentifier(String identifier){
return locate.get(identifier);
}
2023-02-03 17:53:42 +01:00
}