/* 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_COMPOSITE_ADDRESS_HPP
#define NMM_COMPOSITE_ADDRESS_HPP NMM_COMPOSITE_ADDRESS_HPP

#include "nmm/nmm_prefix.hpp"

#include "TSAddress.hpp"

#include "nmm/comm/serialize/SequenceValue.hpp"

#include "visibility.hpp"

namespace NMM {
  
  /** A %TSAddress which is composed of other TSAddresses.
   * A %CompositeAddress consists of an arbitrary number of other
   * %TSAddress objects which are called child addresses. Composite
   * addresses are used with composite transport strategies to specify
   * child transport strategies and their roles. The specific roles
   * are defined by subclasses of %CompositeAddress.
   *
   * A composite address must be complete, or it can not be used. This
   * means that all communication roles must be assigned an address. A
   * child address can be assigned to multiple roles.
   *
   * Note that the strategy type of an address must be suitable for
   * the communication role it is assigned to.
   *
   * Communication roles are defined in subclasses of
   * %CompositeAddress. The base class has no roles and is therefore
   * abstract.
   *
   * The vector of child addresses may contain null pointers. Although
   * null addresses should not be added explicitly to a composite
   * address, serialization and deserrialization might introduce null
   * pointers if some of the child addresses are not available in the
   * deserializer's name space.
   *
   * @see CompositeStrategy
   */
  class DLLEXPORT CompositeAddress
    : public TSAddress
  {
  public:
    /** @name Constructor & Destructor
     */
    //@{
    /** Constructs a %CompositeAddress with no child addresses.
     *
     * @param ref NMM reference
     * @param strategy_type type of TransportStrategy
     * @param t_info Type of this address
     */
    CompositeAddress(const NMMReference& ref, const string& strategy_type, const TypeInfo& t_info) throw();
    
    /** Copy constructor.
     *
     * @param addr reference to address that should be copied
     */
    CompositeAddress(const CompositeAddress& addr) throw();
    
    /** Destructor.
     */
    ~CompositeAddress();
    
    /** Virtual copy constructor.
     *
     * @return copy to a new instance of CompositeAddress
     */
    virtual CompositeAddress* copy() const throw() = 0;
    //@}
    
    /** @name Child Addresses
     */
    //@{
    /** Adds a child address.
     *
     * This method adds a child address to the composite and returns the index that is assigned to it.
     *
     * @param address Address to add
     * @return The index of the child address
     */
    unsigned int addAddress(const TSAddress& address) throw();
    
    /** Returns number of child addresses.
     *
     * This method returns the number of child addresses. Valid child address indices are between 0 and
     * the value returned by this method minus 1.
     *
     * @return The number of child addresses in this CompositeAddress
     */
    unsigned int getNumberOfAddresses() const throw();
    
    /** Returns child address.
     * Note that addresses may be 0 after serialization.
     *
     * @param ts_index Index of child address
     * @return The child address with the given index
     */
    const TSAddress* getAddress(unsigned int ts_index) const throw();

    /** Tests if this composite address is complete.
     *
     * A composite address is complete if all roles have been assigned
     * a child address.
     * 
     * @return true if composite address is complete, otherwise false.
     */
    virtual bool isComplete() const throw() = 0;
    //@}
    
  private:
    /** Register all attributes for serialization/deserialization.
     */
    void registerAttributes() throw();
    
  private:
    SequenceValue<TSAddress> __child_addresses;  ///< Addresses for sub-bindings.
  };
  
}

#include "nmm/nmm_suffix.hpp"

#endif
