package jas.util; import java.util.Enumeration; import java.util.Observer; import java.util.Vector; /** * A CommandTargetManager manages a set of CommandSources and a set of CommandProcessors, * and figure out the wiring from the CommandSources to the CommandTargets within the CommandProcessors. * The CommandProcessors can be dynamically added and removed from the CommandTargetManager, * as sets of commands become available or not. */ final public class CommandTargetManager { public synchronized void add(CommandProcessor processor) { processors.addElement(processor); if (started) { Enumeration es = sources.elements(); while (es.hasMoreElements()) { CommandSource s = (CommandSource) es.nextElement(); if (s.getTarget() == null) { String command = s.getCommand(); CommandTarget target = processor.acceptCommand(command); if (target != null) { if (s.setTarget(target) && s instanceof Observer) processor.addObserver((Observer) s); } } } } processor.setManager(this); } public synchronized void remove(CommandProcessor processor) { processors.removeElement(processor); if (started) { Enumeration es = sources.elements(); while (es.hasMoreElements()) { CommandSource s = (CommandSource) es.nextElement(); CommandTarget target = s.getTarget(); if (target != null) { if (target.getProcessor() == processor) { s.clearTarget(); if (s instanceof Observer) processor.deleteObserver((Observer) s); } } } } processor.setManager(null); } public synchronized void add(CommandSource source) { sources.addElement(source); if (started) { linkCommandSource(source); } } public synchronized void remove(CommandSource source) { sources.removeElement(source); final String command = source.getCommand(); final Enumeration ep = processors.elements(); while (ep.hasMoreElements()) { final CommandProcessor p = (CommandProcessor) ep.nextElement(); final CommandTarget t = p.acceptCommand(command); if (t != null) { source.clearTarget(); if (source instanceof Observer) p.deleteObserver((Observer) source); } } } public synchronized void start() { started = true; Enumeration es = sources.elements(); while (es.hasMoreElements()) { linkCommandSource((CommandSource) es.nextElement()); } } /** * This method just links the CommandSource to the first CommandProcessor it hits * that contains a CommandTarget that accepts the CommandSource--which is a problem * if we want to have two simultaneously active CommandProcessors which both contain * (different) CommandTargets of the same name (e.g. the case of the ProgramPage and * the Console window both having a Copy command). */ private void linkCommandSource(final CommandSource s) { final String command = s.getCommand(); final Enumeration ep = processors.elements(); while (ep.hasMoreElements()) { final CommandProcessor p = (CommandProcessor) ep.nextElement(); final CommandTarget t = p.acceptCommand(command); if (t != null) { if (s.setTarget(t) && s instanceof Observer) p.addObserver((Observer) s); } } } private boolean started = false; private final Vector processors = new Vector(); private final Vector sources = new Vector(); }