Fawkes API
Fawkes Development Version
|
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