dependency_onetomany.h

00001 
00002 /***************************************************************************
00003  *  dependency_onetomany.h - One-to-Many dependency constraint
00004  *
00005  *  Created: Tue May 29 14:10:25 2007
00006  *  Copyright  2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __UTILS_CONSTRAINTS_DEPENDENCY_ONETOMANY_H_
00025 #define __UTILS_CONSTRAINTS_DEPENDENCY_ONETOMANY_H_
00026 
00027 #include <utils/constraints/dependency.h>
00028 
00029 #include <list>
00030 
00031 namespace fawkes {
00032 
00033 
00034 /** @class OneToManyDependency <utils/constraints/dependency_onetomany.h>
00035  * One-to-Many dependency constraint.
00036  * This dependency constraint models a 1-to-n relationship. There is one
00037  * object called provider, that any number of other objects (dependants)
00038  * rely on.
00039  *
00040  * The provider is unique and only one provider may exist at any one time.
00041  * There may be an arbitrary number of dependants. Dependants may only be
00042  * added if there is already a provider.
00043  *
00044  * Dependants can always be removed. The provider can only be removed if
00045  * there are no more dependants.
00046  *
00047  * @author Tim Niemueller
00048  */
00049 
00050 template <class Provider, class Dependant>
00051   class OneToManyDependency
00052 {
00053  public:
00054   OneToManyDependency();
00055   virtual ~OneToManyDependency();
00056 
00057   virtual void add(Provider *p);
00058   virtual void add(Dependant *d);
00059   virtual void remove(Provider *p);
00060   virtual void remove(Dependant *d);
00061 
00062   virtual bool can_add(Provider *p);
00063   virtual bool can_add(Dependant *d);
00064   virtual bool can_remove(Provider *p);
00065   virtual bool can_remove(Dependant *d);
00066 
00067   virtual Provider *                 provider();
00068   virtual std::list<Dependant *> &   dependants();
00069 
00070  private:
00071   Provider                 *_provider;
00072   std::list<Dependant *>    _dependants;
00073 };
00074 
00075 
00076 /** Constructor. */
00077 template <class Provider, class Dependant>
00078   OneToManyDependency<Provider, Dependant>::OneToManyDependency()
00079 {
00080   _provider = 0;
00081   _dependants.clear();
00082 }
00083 
00084 
00085 /** Destructor. */
00086 template <class Provider, class Dependant>
00087   OneToManyDependency<Provider, Dependant>::~OneToManyDependency()
00088 {
00089   _dependants.clear();
00090 }
00091 
00092 
00093 /** Add provider object.
00094  * This will add the provider to this dependency or throw an exception if there is
00095  * already a provider.
00096  * @param p provider object to add
00097  * @exception DependencyViolationException thrown, if a second provider is added
00098  */
00099 template <class Provider, class Dependant>
00100 void
00101 OneToManyDependency<Provider, Dependant>::add(Provider *p)
00102 {
00103   if ( (_provider != 0) && (p != _provider) ) {
00104     throw DependencyViolationException("Different provider already set");
00105   } else {
00106     _provider = p;
00107   }
00108 }
00109 
00110 
00111 /** Add dependant object.
00112  * This will add the dependant to this dependency or throw an exception if there is
00113  * no provider.
00114  * @param d dependant object to add
00115  * @exception DependencyViolationException thrown, if no provider has been set
00116  */
00117 template <class Provider, class Dependant>
00118 void
00119 OneToManyDependency<Provider, Dependant>::add(Dependant *d)
00120 {
00121   if (_provider == 0) {
00122     throw DependencyViolationException("No provider set, cannot accept dependant");
00123   } else {
00124     _dependants.push_back(d);
00125   }
00126 }
00127 
00128 
00129 /** Remove provider object.
00130  * @param p provider object to remove
00131  * @exception DependencyViolationException thrown, if the provider should be removed
00132  * while there is still at least one dependant.
00133  */
00134 template <class Provider, class Dependant>
00135 void
00136 OneToManyDependency<Provider, Dependant>::remove(Provider *p)
00137 {
00138   if ( ! _dependants.empty() ) {
00139     throw DependencyViolationException("There are still dependants of provider, "
00140                                        "cannot accept removal of provider");
00141   }
00142   if ( p == _provider )  _provider = 0;
00143 }
00144 
00145 
00146 /** Remove a depending object
00147  * @param d depending object to remove
00148  */
00149 template <class Provider, class Dependant>
00150 void
00151 OneToManyDependency<Provider, Dependant>::remove(Dependant *d)
00152 {
00153   if ( d != 0 ) {
00154     _dependants.remove(d);
00155   }
00156 }
00157 
00158 
00159 /** Check if provider can be added.
00160  * @param p provider object to add
00161  * @return true, if add(p) would succeed, false otherwise
00162  */
00163 template <class Provider, class Dependant>
00164 bool
00165 OneToManyDependency<Provider, Dependant>::can_add(Provider *p)
00166 {
00167   return ( (_provider == 0) || (p == _provider) );
00168 }
00169 
00170 
00171 /** Check if dependant can be added.
00172  * @param d dependant object to add
00173  * @return true, if add(d) would succeed, false otherwise
00174  */
00175 template <class Provider, class Dependant>
00176 bool
00177 OneToManyDependency<Provider, Dependant>::can_add(Dependant *d)
00178 {
00179   return (_provider != 0);
00180 }
00181 
00182 
00183 /** Check if provider can be removed.
00184  * @param p provider object to remove
00185  * @return true, if remove(p) would succeed, false otherwise
00186  */
00187 template <class Provider, class Dependant>
00188 bool
00189 OneToManyDependency<Provider, Dependant>::can_remove(Provider *p)
00190 {
00191   return _dependants.empty();
00192 }
00193 
00194 
00195 /** Check if dependant can be removed.
00196  * @param d depending object to remove
00197  * @return always true
00198  */
00199 template <class Provider, class Dependant>
00200 bool
00201 OneToManyDependency<Provider, Dependant>::can_remove(Dependant *d)
00202 {
00203   return true;
00204 }
00205 
00206 
00207 /** Get provider.
00208  * @return provider if set, 0 otherwise
00209  */
00210 template <class Provider, class Dependant>
00211 Provider *
00212 OneToManyDependency<Provider, Dependant>::provider()
00213 {
00214   return _provider;
00215 }
00216 
00217 
00218 /** Get dependants.
00219  * @return list of dependants.
00220  */
00221 template <class Provider, class Dependant>
00222 std::list<Dependant *> &
00223 OneToManyDependency<Provider, Dependant>::dependants()
00224 {
00225   return _dependants;
00226 }
00227 
00228 
00229 } // end namespace fawkes
00230 
00231 #endif

Generated on Tue Feb 22 13:31:27 2011 for Fawkes API by  doxygen 1.4.7