package model; import annotations.Assoc; import java.util.HashMap; import java.util.Map; /** * A group of observers with different types registered. */ public class GroupObserver implements Observer { /** * The map. Because Java doesn't have dependent maps, they are left here as unchecked. */ @Assoc(partOf = true) private final Map map = new HashMap<>(); /** * EFFECTS: Register a data type with an observer. Override existing registrations with the same type. * REQUIRES: cls != null, obs != null. */ public void register(Class cls, Observer obs) { map.put(cls, obs); } /** * EFFECTS: Notify the registered observer based on the type of 'o' with given arguments. * Does nothing if no registration found. Subclasses are supported as long as a parent class observer is registered. * Specific type match takes priority. Non-specific type match is not guaranteed to be the closest. * REQUIRES: o != null, direction be DIRECTION_*, index >= 0 or == INDEX_NOT_IN_LIST. */ @Override public void accept(Object o, int direction, int i) { Observer obs = map.get(o.getClass()); if (obs == null) { Class supertype = map.keySet().stream().filter(clz -> clz.isInstance(o)).findFirst().orElse(null); if (supertype == null) { return; } obs = map.get(supertype); } obs.accept(o, direction, i); } /** * EFFECTS: Count the observers. */ public int getRegisteredObserverCount() { return map.size(); } }