/*************************************************************************** * * * Registry.java * * ------------------- * * date : 16.08.2004 * * copyright : (C) 2004-2008 Distributed and * * Mobile Systems Group * * Lehrstuhl fuer Praktische Informatik * * Universitaet Bamberg * * http://www.uni-bamberg.de/pi/ * * email : sven.kaffille@uni-bamberg.de * * karsten.loesing@uni-bamberg.de * * * * * ***************************************************************************/ /*************************************************************************** * * * This program 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 2 of the License, or * * (at your option) any later version. * * * * A copy of the license can be found in the license.txt file supplied * * with this software or at: http://www.gnu.org/copyleft/gpl.html * * * ***************************************************************************/ package de.uniba.wiai.lspi.chord.com.local; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import de.uniba.wiai.lspi.chord.data.URL; import de.uniba.wiai.lspi.util.logging.Logger; /** * This class represents a registry for {@link ThreadEndpoint endpoints}that * can be used to build up a chord network within the same JVM with help of Java * Threads. This Registry is a singleton so that there is only one instance of * this in the JVM. A reference to the singleton can be obtained by invocation * of {@link #getRegistryInstance()}. * * @author sven * @version 1.0.5 */ public final class Registry { /** * Logger for instances of this. */ private final static Logger logger = Logger.getLogger(Registry.class.getName()); /** * Reference to the registry singleton. */ private static Registry registry; /** * Stores the references to the registered {@ThreadEndpoint endpoints} . */ private Map<URL, ThreadEndpoint> registeredEndpoints = new HashMap<URL, ThreadEndpoint>(); // TODO Hashtable for synchronization? /** * Stores references to the proxies in use by nodes. Key: {@link String} (name of node), Value: {@link List} of {@link ThreadProxy proxies}. */ private Map<URL, List<ThreadProxy>> proxiesInUse = new HashMap<URL, List<ThreadProxy>>(); // TODO Hashtable for synchronization? /** * Create an instance of Reqistry. */ private Registry() { /* nothing to do here */ } /** * Add the given proxy used by the node with <code>nodeName</code>. * * @param url * The url of the node that uses the proxy. * @param proxy * The {@link ThreadProxy proxy}to add. */ public void addProxyUsedBy(URL url, ThreadProxy proxy) { if (!this.registeredEndpoints.containsKey(url)) { return; } List<ThreadProxy> pList = this.proxiesInUse.get(url); if (pList == null) { pList = new LinkedList<ThreadProxy>(); } pList.add(proxy); this.proxiesInUse.put(url, pList); } /** * Get a reference to the {@link List}of proxies used by the node with * <code>nodeName</code>. * * @param url * The url of the node. * @return {@link List}of {@link ThreadProxy proxies}that are used by the * node with <code>nodeName</code>. May return <code>null</code> * if there are no proxies in use by the node. */ public List<ThreadProxy> getProxiesInUseBy(URL nodeName) { logger.debug("getProxiesInUseBy(" + nodeName + ")"); return this.proxiesInUse.get(nodeName); } /** * Removes the {@link ThreadProxy proxies} used by the node * with <code>nodeName</code>. * * @param url The url of the node, for that the proxies * should be removed. */ public void removeProxiesInUseBy(URL nodeName) { logger.debug("removeProxiesInUseBy(" + nodeName + ")"); this.proxiesInUse.remove(nodeName); } /** * Register the given {@link ThreadEndpoint endpoint}so that it can be * looked up via {@link #lookup(String)}. * * @param endpoint * The {@link ThreadEndpoint}to register. */ public void bind(ThreadEndpoint endpoint) { URL name = endpoint.getURL(); logger.debug("Binding endpoint: " + endpoint + "with name " + name); /* if there is not already an endpoint for that name */ Object temp = this.registeredEndpoints.get(name); if (temp == null) { /* bind given endpoint to name */ this.registeredEndpoints.put(name, endpoint); logger.debug("Endpoint " + endpoint + " bound."); } else { logger.warn("Endpoint " + endpoint + " NOT BOUND!!! " + temp + " already registered under " + name); } } /** * Remove the given {@link ThreadEndpoint endpoint}from the registry. * * @param endpoint * {@link ThreadEndpoint}to remove. */ public void unbind(ThreadEndpoint endpoint) { logger.debug("Unbinding endpoint: " + endpoint); this.registeredEndpoints.remove(endpoint.getURL()); logger.debug("Endpoint " + endpoint + " removed from registry."); } /** * This method looks up the {@link ThreadEndpoint endpoint}for the * node with the given * name. If no endpoint is found <code>null</code> is returned. * * @param url * The url of the node, for which the * {@link ThreadEndpoint endpoint}is looked up. * * @return Reference to the {@link ThreadEndpoint endpoint}of node with * name "<code>name</code>". May be <code>null</code> if no * such reference exists. */ public ThreadEndpoint lookup(URL url) { logger.debug("Looking up endpoint for " + url); ThreadEndpoint ep = this.registeredEndpoints.get(url); logger.debug("Endpoint for " + url + ": " + ep); return ep; } /** * Returns an array of all registered endpoints. * * @return Array of all registered {@link ThreadEndpoint endpoints}. If no * endpoint is registered an array of length 0 is returned. */ public Map<URL, ThreadEndpoint> lookupAll() { return this.registeredEndpoints; /* * synchronized (this.registeredEndpoints){ ThreadEndpoint[] endpoints = * new ThreadEndpoint[registeredEndpoints.size()]; Iterator iterator = * this.registeredEndpoints.values().iterator(); int index = 0; while * (iterator.hasNext()) { endpoints[index] = * (ThreadEndpoint)iterator.next(); index++; } return endpoints; } */ } /** * Get a reference to the registry singleton. * This method is not thread-safe! * * @return Reference to the registry singleton. */ public static Registry getRegistryInstance() { if (registry == null) { logger.debug("Creating registry singleton. "); registry = new Registry(); logger.debug("Registry singleton created. "); } return registry; } /** * Overwritten from {@link java.lang.Object}. * * @return String representation of this. */ public String toString() { StringBuilder buffer = new StringBuilder(); buffer.append("[Singleton registry of ThreadEndpoints "); buffer.append("with "); buffer.append(this.registeredEndpoints.size()); buffer.append(" endpoints registered]"); return buffer.toString(); } /** * Shutdown this registry. */ public void shutdown(){ for (ThreadEndpoint endpoint : this.registeredEndpoints.values()) { endpoint.crash(); } } }