/* 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_CONNECTOR_ACCEPTOR_HPP
#define NMM_CONNECTOR_ACCEPTOR_HPP NMM_CONNECTOR_ACCEPTOR_HPP

#include "nmm/nmm_prefix.hpp"

#include "ObjectAcceptor.hpp"

#include "visibility.hpp"

namespace NMM {
  
  class IConnectionManager;
  class ConnectorAddress;
  
  /**
   *  @brief Virtual acceptor base class
   *
   *  A connector acceptor is an %ObjectAcceptor which is triggered by the %ConnectionManager in response to a
   *  conenction request. Its purpose it to simulate reliable connection setup for transport strategies that
   *  don't provide reliable connection setup of their own.
   *
   *  @see ConnectorAddress
   *  @see ConnectionManager
   */
  class DLLEXPORT ConnectorAcceptor :
    public ObjectAcceptor
  {
  public:
    /**
     *  @name Constructor & Destructor
     */
    //@{
    /** Constructs a %ConnectorAcceptor.
     *  
     *  @param strategy_type Type of transport strategy
     */
    ConnectorAcceptor(const std::string& strategy_type);
    
    /** Virtual copy constructor.
     */
    virtual ConnectorAcceptor* copy() const throw();
    
    /** Virtual destructor.
     */
    virtual ~ConnectorAcceptor();
    //@}
    
    /** 
     *  @name Remote Interface
     */
    //@{
    /** Handles connection request.
     *
     *  This method is called by the ConnectionManager when it has received a connection request.
     *  The implementation is expected to handle this connection request and create a suitable
     *  partner TransportStrategy. It should also return the local address of the partner strategy
     *  and its NMM reference.
     *
     *  @param remote_addr Fully specified address of remote transport strategy
     *  @param local_addr Returns the fully specified address of local transport strategy
     *  @exception BindingException if the connection request has failed
     */
    virtual void handleConnect(const ConnectorAddress* remote_addr, ConnectorAddress*& local_addr)
      throw (const BindingException&);
    //@}
    
    /** @name Local Interface
     */
    //@{
    /** Requests a connection.
     *
     *  This method is called by the ConnectionManager when a local transport strategy requests
     *  a connection to a remote host. The implementation is expected to forward the request to
     *  the remote host. This is typically done by calling handleConnect on the remote IConnectionManager
     *  interface, but different connection setup strategies (such as SIP) may do something else
     *  entirely.
     *
     *  @param local_addr Fully specified address of the local transport strategy
     *  @param remote_addr Returns the fully specified address of the remote transport strategy
     *  @param remote_icm Connection manager interface on the remote side
     *  @exception BindingException if the connection could not be set up
     */
    virtual void connect(const ConnectorAddress* local_addr, ConnectorAddress*& remote_addr, IConnectionManager* remote_icm)
      throw(const BindingException&);
    
    /** Returns strategy type.
     *
     *  This method returns the type of transport strategy that this connector can handle.
     *
     *  @return The startegy type of this connector
     */
    const std::string& getStrategyType() const throw();
    //@}
    
  private:
    std::string __strategy_type;          ///< Transport strategy type
  };
  
  
  inline const std::string& ConnectorAcceptor::getStrategyType() const throw() {
    return __strategy_type;
  }
  
}

#include "nmm/nmm_suffix.hpp"

#endif
