/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM 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; only version 2 of the License.      
 * 
 * NMM 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 NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#ifndef NMM_LOCALNODEFACTORY_HPP
#define NMM_LOCALNODEFACTORY_HPP

#include "nmm/nmm_prefix.hpp"

#include "NodeFactory.hpp"
#include "nmm/utils/Singleton.hpp"

#include "visibility.hpp"

namespace NMM {

class FactoryException;
class Node;
class Dll;

/** The LocalNodeFactory implements a NodeFactory for nodes that are managed by the LocalRegistry.
  * This basic implementation offers also the registration of so called FactoryObjects wich can be
  * used to instantiate nodes. These FactoryObjects use the new() operator to create the node and
  * delete() for destruction.
  */
class DLLEXPORT LocalNodeFactory : public NodeFactory {
DECLARE_SINGLETON(LocalNodeFactory, CreateUsingNew, DefaultLifetime, MultiThreaded);
friend class CreateUsingNew<LocalNodeFactory>;
public:

  /** @name factory methods
   * These methods can be used to create and destroy Nodes.
   */
  //@{
  /** This method creates a Node from a given FactoryTicket. 
   *
   * If the node can not be created for some reason an exception is thrown. 
   * The FactoryTicket is creates by a Registry, if the node is reserved. After
   * this method the FactoryTicket is invalid and can not be used again.
   *
   * @param ticket The ticket is created by a registry and allows the maintainer to create the node.
   * @return A refernce to the new Node
   */
  virtual  Node& createNode (const FactoryTicket& ticket)
    throw (const FactoryException& );

  /** This method releases a node. 
   *
   * The NodeFactory can delete this node or store it for a later use.
   *
   * @param node The node that should be released
   */
  virtual  void  releaseNode (const Node& node)
    throw (const FactoryException& );
  //@}
  
  /** @name registration methods
   * These methods can be used to register/unregister nodes
   */
  //@{
  /** This method registers a FactoryObject with a ObjectID. 
   *
   * The FactoryObject is used to create the node.
   * The ObjectID is created from a Registry. If the application requests a Node (which is stored in the
   * FactoryTicket), the LocalNodeFactory searches the corresponding FactoryObject and creates the Node.
   *
   * @param node_id The ObjectID which is used to identify the FactoryObject
   * @param factory_object The FactoryObject which can create the node
   */
  virtual  void registerNode(const ObjectID& node_id, const FactoryObject& factory_object);

  /** This method unregisters the FactoryObject registered with given ObjectID.
   *
   * @param node_id The ObjectID for the FactoryObject that should be removed
   */
  virtual  void unregisterNode(const ObjectID& node_id);
  //@}
  
  /** @name Plugin registration
   */
  //@{
  /** This method registers a Plugin.
   *
   * @param plugin plug-in to register
   */
  virtual void registerPlugin(Plugin* plugin);
  
  /** This method registers a Plugin.
   *
   * @param plugin plug-in to register
   */
  virtual void unregisterPlugin(const Plugin* plugin);
  //@}
  
private:
  /** @name Constructor/Destructor
   * These methods are private
   */
  //@{
  /** Constructor.
   */
  LocalNodeFactory();
  
  /** Destructor.
   */
  virtual ~LocalNodeFactory();
  
  /** Disabled Copy-Constructor.
   *
   * @param local_factory LocalNodeFactory to copy
   */
  LocalNodeFactory(const LocalNodeFactory& local_factory);
  //@}
private:
  map<ObjectID, FactoryObject*>   __factory_map;    ///< stores the registered FactoryObjects which create the nodes
  map<Node*, FactoryObject*>    __node_list;      ///< stores the created Nodes with  the corresponding FactoryObjects which can destroy the node
};

/* Typedef to access the LocalNodeFactory with the method call SLocalNodeFactory::getInstance() */
typedef LocalNodeFactory::Singleton SLocalNodeFactory;

} //end namespace
#include "nmm/nmm_suffix.hpp"

#endif
