// Copyright 2011, 2012 Tony Garnock-Jones . // // This file is part of Hop. // // Hop is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Hop is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public // License for more details. // // You should have received a copy of the GNU General Public License // along with Hop. If not, see . // package hop; import java.io.Flushable; import java.io.IOException; import java.lang.ref.WeakReference; import java.util.*; /** */ public class NodeContainer implements Flushable { public String _name; public Map> _directory; public NodeContainer() { this(UUID.randomUUID().toString()); } public NodeContainer(String name) { _name = name; _directory = new Hashtable>(); } public String getName() { return _name; } public synchronized boolean bind(String name, Node n) { WeakReference ref = _directory.get(name); if (ref != null && ref.get() != null) { return false; } ref = new WeakReference(n); _directory.put(name, ref); return true; } public synchronized boolean unbind(String name) { if (!_directory.containsKey(name)) return false; _directory.remove(name); return true; } public void flush() throws IOException { ArrayList fs = new ArrayList(); synchronized (this) { for (Map.Entry> e : _directory.entrySet()) { Node n = e.getValue().get(); if (n instanceof Flushable) { fs.add((Flushable) n); } } } for (Flushable f : fs) { f.flush(); } } public void flush(String name) throws IOException { Flushable f; synchronized (this) { WeakReference ref = _directory.get(name); if (ref == null) return; Node n = ref.get(); if (n == null) return; if (!(n instanceof Flushable)) return; f = ((Flushable) n); } f.flush(); } public synchronized void unbindReferencesTo(Node n) { for (Map.Entry> e : _directory.entrySet()) { if (e.getValue().get() == n) { _directory.remove(e.getKey()); } } } public synchronized Node lookup(String name) { WeakReference r = _directory.get(name); return (r == null) ? null : r.get(); } public boolean post(String sink, Object name, Object message, Object token) { return send(sink, SexpMessage.post(name, message, token)); } public boolean send(String name, Object message) { Node n = lookup(name); if (n == null) { System.err.println("Warning: sending to nonexistent node " + name + "; message " + message); return false; } n.handle(message); return true; } }