/* * Tigase Jabber/XMPP Server * Copyright (C) 2004-2012 "Artur Hefczyc" <artur.hefczyc@tigase.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. Look for COPYING file in the top folder. * If not, see http://www.gnu.org/licenses/. * * $Rev$ * Last modified by $Author$ * $Date$ */ package tigase.server; import java.util.LinkedHashMap; import java.util.Map; /** * This is an archetype of a special types of classes which collect some data * from Tigase components or provide these data to components. They normally * do not process normall packets and are usually accessed by admins via ad-hoc * commands. Good examples of such components are <code>StatisticsCollector</code> * or <code>Configurator</code>.<p/> * Extensions of these class can process packets addresses to the component via * <code>processPacket(Packet packet, Queue<Packet> results)</code> method. * Alternatively scripting API can be used via ad-hoc commands.<p/> * The class does not have any queues buffering packets or separate threads for * packets processing. All packets are processed from <code>MessageRouter</code> * threads via <code>processPacket(Packet packet, Queue<Packet> results)</code> * method. Hence this is important that processing implemented in extensions to the * class does not take long time. In particular no DB processing is expected. * * * Created: Tue Nov 22 22:57:44 2005 * * @param <E> * @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a> * @version $Rev$ */ public abstract class AbstractComponentRegistrator<E extends ServerComponent> extends BasicComponent implements ComponentRegistrator { private long packetId = 0; /** * A collection of server components which implement special interface, related to the * functionality provided by extension of the class. */ protected Map<String, E> components = new LinkedHashMap<String, E>(); /** * Creates a new <code>AbstractComponentRegistrator</code> instance. * */ public AbstractComponentRegistrator() {} /** * Method provides a callback mechanism signaling that a new component implementing * special interface has been added to the internal <code>components</code> collection. * * * @param component is a reference to the component just added to the collection. */ public abstract void componentAdded(E component); /** * Method provides a callback mechanism signaling that a component implementing * special interface has been removed from the internal <code>components</code> * collection. * * * @param component is a reference to the component removed from the collection. */ public abstract void componentRemoved(E component); /** * Method checks whether the component provides as method parameter is correct type * that is implements special interface or extends special class. Result of the method * determines whether the component can be added to the internal <code>components</code> * collection. * * * @param component is a reference to the component being checked. * * @return a <code>boolean</code> value of <code>true</code> if the component is of a * correct type and <code>false</code> otherwise. */ public abstract boolean isCorrectType(ServerComponent component); /** * Method checks whether the component is of a correct type, adds it to the internal * <code>components</code> collection and calls <code>componentAdded(...)</code> callback. * * * @param component a reference to the component which is being added to the intenal * collection. * * @return a <code>boolean</code> value of <code>true</code> if the component * has been added to the internal collection and <code>false</code> otherwise. */ @SuppressWarnings("unchecked") @Override public boolean addComponent(ServerComponent component) { if (isCorrectType(component)) { components.put(component.getName(), (E) component); componentAdded((E) component); return true; } else { return false; } } /** * Method removes specified component from the internal <code>components</code> * collection and calls <code>componentRemoved(...)</code> callback method. * * @param component is a reference to the component being removed. * @return a <code>boolean</code> value of <code>true</code> if the component * has been removed from the internal collection and <code>false</code> otherwise. */ @SuppressWarnings("unchecked") @Override public boolean deleteComponent(ServerComponent component) { components.remove(component.getName()); componentRemoved((E) component); return true; } /** * Method returns a component for a specified component name from internal * <code>components</code> collection or <code>null</code> of there is no such * component in the collection. * * * @param name is a <code>String</code> value of the component name. * * @return a reference to the component found in the internal collection or * <code>null</code> if no component has been found. */ public E getComponent(String name) { return components.get(name); } /** * Method generates and returns an unique packet ID. The ID is unique within running * Tigase instance. The method can be overwritten to change the generation of the * packet ID. * * * @param prefix is a <code>String</code> value of the ID profix or <code>null</code> * if no prefix is necessary. * * @return a <code>String</code> instance of a new packet ID. */ public String newPacketId(String prefix) { StringBuilder sb = new StringBuilder(32); if (prefix != null) { sb.append(prefix).append("-"); } sb.append(getName()).append(++packetId); return sb.toString(); } /** * Method is called when the component is being stopped and potentially removed from * the system to release all resources associated with the component. After a call to * this method no further processing or calls to <code>processPacket</code> or any * ad-hoc commands is expected. * */ @Override public void release() {} } // AbstractComponentRegistrator