import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; public class ChannelNode implements IChannelNode { private Map incoming; private Map outgoing; public ChannelNode() { incoming = new TreeMap<>(); outgoing = new TreeMap<>(); } @Override public void setConnections(Map conmap, Direction dir) throws IllegalArgumentException { if(conmap == null) throw new IllegalArgumentException("connection map is null"); if(dir == null) throw new IllegalArgumentException("direction is null"); if(conmap.containsKey(this)) throw new IllegalArgumentException("connection map contains this node"); int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) incoming = conmap; if(dv >= Direction.OUTGOING.getVal()) outgoing = conmap; } @Override public void setNumConnections(IChannelNode node, Direction dir, int num) throws IllegalArgumentException { if(node == null) throw new IllegalArgumentException("node is null"); if(node == this) throw new IllegalArgumentException("node is self"); if(dir == null) throw new IllegalArgumentException("dir is null"); if(num < 0) throw new IllegalArgumentException("num < 0"); int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) incoming.put(node, num); if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, num); } @Override public void addConnection(IChannelNode node, Direction dir) throws IllegalArgumentException { if(node == null) throw new IllegalArgumentException("node is null"); if(node == this) throw new IllegalArgumentException("node is self"); if(dir == null) throw new IllegalArgumentException("dir is null"); int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) incoming.put(node, incoming.get(node) + 1); if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, outgoing.get(node) + 1); } @Override public void addConnections(Iterable nodes, Direction dir) throws IllegalArgumentException { if(nodes == null) throw new IllegalArgumentException("node is null"); if(dir == null) throw new IllegalArgumentException("dir is null"); nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); int dv = dir.getVal(), incomingV = Direction.INCOMING.getVal(), outgoingV = Direction.OUTGOING.getVal(); nodes.forEach((node) -> { if(dv >= incomingV) incoming.put(node, incoming.get(node) + 1); if(dv >= outgoingV) outgoing.put(node, outgoing.get(node) + 1); }); } @Override public void removeConnection(IChannelNode node, Direction dir) throws IllegalArgumentException { if(node == null) throw new IllegalArgumentException("node is null"); if(node == this) throw new IllegalArgumentException("node is self"); if(dir == null) throw new IllegalArgumentException("dir is null"); int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); if(dv >= Direction.OUTGOING.getVal()) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); } @Override public void removeConnections(Iterable nodes, Direction dir) throws IllegalArgumentException { if(nodes == null) throw new IllegalArgumentException("node is null"); if(dir == null) throw new IllegalArgumentException("dir is null"); nodes.forEach((node) -> {if(node == this) throw new IllegalArgumentException("one of the included nodes is this node");}); int dv = dir.getVal(), incomingV = Direction.INCOMING.getVal(), outgoingV = Direction.OUTGOING.getVal(); nodes.forEach((node) -> { if(dv >= incomingV) incoming.put(node, Math.max(incoming.get(node) - 1, 0)); if(dv >= outgoingV) outgoing.put(node, Math.max(outgoing.get(node) - 1, 0)); }); } @Override public void clearConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) incoming.clear(); if(dv >= Direction.OUTGOING.getVal()) outgoing.clear(); } @Override public boolean connectionExists(IChannelNode node, Direction dir) throws IllegalArgumentException { if(node == null) throw new IllegalArgumentException("node is null"); if(dir == null) throw new IllegalArgumentException("dir is null"); switch (dir) { case INCOMING -> {return incoming.containsKey(node);} case OUTGOING -> {return outgoing.containsKey(node);} case BOTH -> {return (incoming.containsKey(node) && outgoing.containsKey(node));} default -> throw new IllegalStateException("got unknown direction"); } } @Override public int getNumConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); int total = 0; int dv = dir.getVal(); if(dv >= Direction.INCOMING.getVal()) for(int i: incoming.values()) total += i; if(dv >= Direction.OUTGOING.getVal()) for(int i: outgoing.values()) total += i; return total; } @Override public Map getIncomingConnections() { return incoming; } @Override public Map getOutgoingConnections() { return outgoing; } @Override public List> getConnections(Direction dir) throws IllegalArgumentException { if(dir == null) throw new IllegalArgumentException("dir is null"); int dv = dir.getVal(); ArrayList> res = new ArrayList<>(); if(dv >= Direction.INCOMING.getVal()) res.add(incoming); if(dv >= Direction.OUTGOING.getVal()) res.add(outgoing); return res; } @Override public int compareTo(IChannelNode iChannelNode) throws IllegalArgumentException { if(iChannelNode == null) throw new IllegalArgumentException("comparison node is null"); int selfTotal = getNumConnections(Direction.BOTH), theirTotal = iChannelNode.getNumConnections(Direction.BOTH); return selfTotal - theirTotal; } }