package classes; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.UUID; import classes.holonControlUnit.HolonControlUnit; import ui.controller.Control; import ui.model.DecoratedNetwork; import ui.model.Model; public class Holon { public String name = new String(); private Holon parent = null; public ArrayList childHolons = new ArrayList(); private List elements = new ArrayList(); //HolonObject is the lowest representation of a holon. private final HolonObject holonObject; public final boolean isPhysical; public HolonControlUnit holonControlUnit; private String uniqueID; public Model model; public Holon(String name, Model model) { this.name = name; this.holonObject = null; isPhysical = false; this.holonControlUnit = new HolonControlUnit(this); this.uniqueID = UUID.randomUUID().toString(); this.model = model; // System.out.println("Created new Holon "+name+" "+this.uniqueID); } public Holon(HolonObject object, Model model) { holonObject = object; object.holon = this; name = object.getName(); this.holonControlUnit = new HolonControlUnit(this); elements.addAll(object.getElements()); for(HolonElement ele : elements) { ele.holon = this; } isPhysical = true; this.uniqueID = UUID.randomUUID().toString(); this.model = model; // System.out.println("Created new Holon "+name+" "+this.uniqueID); } public void addElement(HolonElement element) { element.holon = this; elements.add(element); } public void removeElement(HolonElement element) { element.holon = null; elements.remove(element); } public int elementsCount() { return elements.size(); } public void addChild(Holon child) { if(!this.model.getHolonsByID().containsKey(child.getUniqueID())) return; child.parent = this; childHolons.add(child); this.holonControlUnit.addSubHolon(child); // System.out.println("Holon "+this.name+" added new child holon "+child.name); } public void addChildHolon(Holon child, int index) { child.parent = this; childHolons.add(index, child); this.holonControlUnit.addSubHolon(child); // System.out.println("Holon "+this.name+" added new child holon "+child.name); } public void removeChildHolon(Holon child) { child.parent = null; childHolons.remove(child); this.holonControlUnit.getHierarchyController().removeSubHolon(child.getUniqueID()); } public void removeFromParent() { if(parent != null) { parent.removeChildHolon(this); } } public int getChildCount() { return childHolons.size(); } public Holon getParent() { return parent; } public void setParent(Holon parent) { // System.out.println("Holon "+this.name+" replaced parent "+this.parent.name+" with "+parent.name); this.parent = parent; this.holonControlUnit.setSuperHolon(parent); } public HolonObject getHolonObject() { return holonObject; } public List getChildView(){ return Collections.unmodifiableList(childHolons); } public List getElementView(){ return Collections.unmodifiableList(elements); } @Override public String toString() { return name; } public void reassignAllChildren(Holon other) { for(Holon child: this.childHolons) { other.addChild(child); } childHolons.clear(); } public void removeAllRefrences() { parent = null; this.childHolons.clear(); this.elements.clear(); } public int getLayer() { return parent != null ? parent.getLayer() + 1 : 0; } public Holon cloneWithoutParent() { Holon cloned = new Holon(this.name, this.model); model.getHolonsByID().put(cloned.getUniqueID(), cloned); cloned.childHolons = this.childHolons; cloned.elements = this.elements; return cloned; } public boolean checkHolonArePhysicalConnected(Holon other, Control control) { HashMap table = control.getSimManager().getActualDecorState().getHolonObjectNetworkTable(); HolonObject a = tryGetAPhysicalHolon(); HolonObject b = other.tryGetAPhysicalHolon(); boolean aHolonIsPureAbstract = a == null || b == null; return aHolonIsPureAbstract || table.get(a) == table.get(b); } private HolonObject tryGetAPhysicalHolon() { if(holonObject != null) { return holonObject; } for(Holon holon : childHolons) { HolonObject object = holon.tryGetAPhysicalHolon(); if(object != null) { return object; } } return null; } public void checkRepairHolarchy(HashMap table, Holon stateHolon) { if(childHolons.isEmpty()) { return; } //To establish the invariant that all child holons are repaired for(Holon other : childHolons) { other.checkRepairHolarchy(table, stateHolon); } //Repair this Holon HolonObject first = tryGetAPhysicalHolon(); if(first == null) { return; } List removeList = new ArrayList(); for(Holon other : childHolons) { HolonObject otherHolonObject = other.tryGetAPhysicalHolon(); boolean isPureAbstract = otherHolonObject == null; if(isPureAbstract) { continue; } boolean isPhysicalConnected = table.get(first) == table.get(otherHolonObject); if(!isPhysicalConnected) { removeList.add(other); } } //Remove holons for(Holon holon : removeList) { holon.removeFromParent(); stateHolon.addChild(holon); } } public void addNewVirtualNeighbor(String virtualNeighbor) { if(!this.equals(virtualNeighbor)) { this.holonControlUnit.addNewVirtualNeighbor(virtualNeighbor); } } public String getUniqueID() { return uniqueID; } }