/* This file is part of leafdigital leafChat. leafChat 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. leafChat 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 leafChat. If not, see <http://www.gnu.org/licenses/>. Copyright 2011 Samuel Marshall. */ package leafchat.core; import java.util.*; import leafchat.core.api.*; /** Provide access to all singleton classes */ public class SingletonManager { // Singleton behaviour (yes, this class is a singleton; yes, that's confusing) /** Single instance */ private static SingletonManager sm = new SingletonManager(); /** @return Single instance */ public static SingletonManager get() { return sm; } /** Private constructor to prevent separate construction */ private SingletonManager() {} // Actual implementation /** Actual storage of singletons */ private Map<Class<? extends Singleton>, Singleton> singletons = new HashMap<Class<? extends Singleton>, Singleton>(); /** * Obtains a singleton object. * @param cInterface Desired class/interface * @return Object of that class * @throws BugException If there is no object of that class */ public<C extends Singleton> C get(Class<C> cInterface) { synchronized(singletons) { Singleton s = singletons.get(cInterface); if(s!=null) return cInterface.cast(s); else throw new BugException("No singleton of class "+cInterface.getName()); } } /** * Adds a new singleton. * @param cInterface Class/interface by which this is referenced * @param s Singleton object * @throws BugException If object is not of desired interface, or there's * already a singleton for it */ public <C extends Singleton> void add(Class<C> cInterface, C s) { if(!cInterface.isAssignableFrom(s.getClass())) { throw new BugException( "Object does not implement singleton class " + cInterface.getName()); } synchronized(singletons) { if(singletons.containsKey(cInterface)) { throw new BugException( "Cannot add second singleton of class " + cInterface.getName()); } singletons.put(cInterface,s); } } /** * Removes an existing singleton. * @param cInterface Class/interface by which this is referenced * @param s Object to remove */ public <C extends Singleton> void remove(Class<C> cInterface, Singleton s) { synchronized(singletons) { if(singletons.get(cInterface) == s) { singletons.remove(cInterface); } else { throw new BugException( "Attempt to remove singleton of class " + cInterface.getName() + ", " + "which is not present or does not match"); } } } }