00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifdef ORO_PRAGMA_INTERFACE
00039 #pragma implementation
00040 #endif
00041 #include "PropertyBag.hpp"
00042 #include "Property.hpp"
00043 #include "types/PropertyDecomposition.hpp"
00044 #include "types/Types.hpp"
00045 #include "Logger.hpp"
00046 #include <algorithm>
00047 #include "rtt-fwd.hpp"
00048
00049 namespace RTT
00050 {
00051 using namespace detail;
00052 using namespace std;
00053
00054 PropertyBag::PropertyBag( )
00055 : mproperties(), type("PropertyBag")
00056 {}
00057
00058 PropertyBag::PropertyBag( const std::string& _type)
00059 : mproperties(), type(_type)
00060 {}
00061
00062 PropertyBag::PropertyBag( const PropertyBag& orig)
00063 : mproperties(), type( orig.getType() )
00064 {
00065 for( const_iterator i = orig.mproperties.begin(); i != orig.mproperties.end(); ++i) {
00066 if ( orig.ownsProperty( *i ) ) {
00067 PropertyBase* copy = (*i)->clone();
00068 this->ownProperty( copy );
00069 } else {
00070 this->add( *i );
00071 }
00072 }
00073 }
00074
00075 PropertyBag::~PropertyBag()
00076 {
00077 this->clear();
00078 }
00079
00080 void PropertyBag::add(PropertyBase *p)
00081 {
00082 this->addProperty(*p);
00083 }
00084
00085 void PropertyBag::remove(PropertyBase *p)
00086 {
00087 this->removeProperty(p);
00088 }
00089
00090 bool PropertyBag::ownProperty(PropertyBase* p)
00091 {
00092 if (p == 0)
00093 return false;
00094 if ( ! p->ready() )
00095 return false;
00096 removeProperty(p);
00097 mproperties.push_back(p);
00098 mowned_props.push_back(p);
00099 return true;
00100 }
00101
00102 bool PropertyBag::ownsProperty(PropertyBase* p) const
00103 {
00104 if (p == 0)
00105 return false;
00106 const_iterator i = std::find(mowned_props.begin(), mowned_props.end(), p);
00107 if ( i != mowned_props.end() )
00108 return true;
00109 return false;
00110 }
00111
00112 bool PropertyBag::addProperty(PropertyBase& p)
00113 {
00114 if (&p == 0)
00115 return false;
00116 if ( ! p.ready() )
00117 return false;
00118 mproperties.push_back(&p);
00119 return true;
00120 }
00121
00122 bool PropertyBag::removeProperty(PropertyBase *p)
00123 {
00124 if (p == 0)
00125 return false;
00126 iterator i = std::find(mproperties.begin(), mproperties.end(), p);
00127 if ( i != mproperties.end() ) {
00128 mproperties.erase(i);
00129 i = std::find(mowned_props.begin(), mowned_props.end(), p);
00130 if ( i != mowned_props.end() ) {
00131 delete *i;
00132 mowned_props.erase(i);
00133 }
00134 return true;
00135 }
00136 return false;
00137 }
00138
00139 void PropertyBag::clear()
00140 {
00141 mproperties.clear();
00142 for ( iterator i = mowned_props.begin();
00143 i != mowned_props.end();
00144 i++ )
00145 {
00146 delete *i;
00147 }
00148 mowned_props.clear();
00149 }
00150
00151 void PropertyBag::list(std::vector<std::string> &names) const
00152 {
00153 for ( const_iterator i = mproperties.begin();
00154 i != mproperties.end();
00155 i++ )
00156 {
00157 names.push_back( (*i)->getName() );
00158 }
00159 }
00160
00161 std::vector<std::string> PropertyBag::list() const
00162 {
00163 std::vector<std::string> names;
00164 for ( const_iterator i = mproperties.begin();
00165 i != mproperties.end();
00166 i++ )
00167 {
00168 names.push_back( (*i)->getName() );
00169 }
00170 return names;
00171 }
00172
00173 PropertyBag::Properties PropertyBag::getProperties(const std::string& name) const
00174 {
00175 Properties names;
00176 for ( const_iterator i = mproperties.begin();
00177 i != mproperties.end();
00178 i++ )
00179 {
00180 if ( (*i)->getName() == name )
00181 names.push_back( (*i) );
00182 }
00183 return names;
00184 }
00185
00186
00187 void PropertyBag::identify( PropertyIntrospection* pi ) const
00188 {
00189 for ( const_iterator i = mproperties.begin();
00190 i != mproperties.end();
00191 i++ )
00192 {
00193 (*i)->identify(pi);
00194 }
00195 }
00196
00197 void PropertyBag::identify( PropertyBagVisitor* pi ) const
00198 {
00199 for ( const_iterator i = mproperties.begin();
00200 i != mproperties.end();
00201 i++ )
00202 {
00203 (*i)->identify(pi);
00204 }
00205 }
00206
00211 struct FindProp : public std::binary_function<const base::PropertyBase*,const std::string, bool>
00212 {
00213 bool operator()(const base::PropertyBase* b1, const std::string& b2) const { return b1->getName() == b2; }
00214 };
00217 PropertyBase* PropertyBag::find(const std::string& name) const
00218 {
00219 const_iterator i( std::find_if(mproperties.begin(), mproperties.end(), std::bind2nd(FindProp(), name ) ) );
00220 if ( i != mproperties.end() )
00221 return ( *i );
00222 return 0;
00223 }
00224
00225 base::PropertyBase* PropertyBag::getProperty(const std::string& name) const
00226 {
00227 const_iterator i( std::find_if(mproperties.begin(), mproperties.end(), std::bind2nd(FindProp(), name ) ) );
00228 if ( i != mproperties.end() )
00229 return *i;
00230 return 0;
00231 }
00232
00233
00234 PropertyBag& PropertyBag::operator=(const PropertyBag& orig)
00235 {
00236 if(this == &orig)
00237 return *this;
00238
00239 this->clear();
00240
00241 const_iterator i = orig.getProperties().begin();
00242 while (i != orig.getProperties().end() )
00243 {
00244 add( (*i) );
00245 ++i;
00246 }
00247 this->setType( orig.getType() );
00248 return *this;
00249 }
00250
00251 PropertyBag& PropertyBag::operator<<=(const PropertyBag& source)
00252 {
00253
00254 const_iterator it(source.getProperties().begin());
00255 while ( it != source.getProperties().end() )
00256 {
00257 PropertyBase* mine = find( (*it)->getName() );
00258 if (mine != 0)
00259 remove(mine);
00260 add( (*it) );
00261 ++it;
00262 }
00263 this->setType( source.getType() );
00264 return *this;
00265 }
00266
00267 template<>
00268 bool Property<PropertyBag>::update( const Property<PropertyBag>& orig)
00269 {
00270 if ( !ready() )
00271 return false;
00272 if ( _description.empty() )
00273 _description = orig.getDescription();
00274 return updateProperties( this->_value->set(), orig.rvalue() );
00275 }
00276
00277 template<>
00278 bool Property<PropertyBag>::refresh( const Property<PropertyBag>& orig)
00279 {
00280 if ( !ready() )
00281 return false;
00282 return refreshProperties( this->_value->set(), orig.rvalue() );
00283 }
00284
00285 template<>
00286 bool Property<PropertyBag>::copy( const Property<PropertyBag>& orig)
00287 {
00288 if ( !ready() )
00289 return false;
00290 _name = orig.getName();
00291 _description = orig.getDescription();
00292 return copyProperties( this->_value->set(), orig.rvalue() );
00293 }
00294
00295 std::ostream& operator<<(std::ostream& os, const PropertyBag& bag) {
00296 int size = bag.size();
00297 os << "[[";
00298 for(int i=0; i != size; ++i) {
00299 os << bag.getItem(i)->getName() << "='"<< bag.getItem(i) <<"'"<<endl;
00300 }
00301 os << "]]";
00302
00303 return os;
00304 }
00305
00306 std::istream& operator>>(std::istream& is, PropertyBag& bag) { return is; }
00307
00308
00309 PropertyBase* findProperty(const PropertyBag& bag, const std::string& nameSequence, const std::string& separator)
00310 {
00311 PropertyBase* result;
00312 Property<PropertyBag>* result_bag;
00313 std::string token;
00314 std::string::size_type start = 0;
00315 if ( separator.length() != 0 && nameSequence.find(separator) == 0 )
00316 start = separator.length();
00317 std::string::size_type len = nameSequence.find(separator, start);
00318 if (len != std::string::npos) {
00319 token = nameSequence.substr(start,len-start);
00320 start = len + separator.length();
00321 if ( start >= nameSequence.length() )
00322 start = std::string::npos;
00323 }
00324 else {
00325 token = nameSequence.substr(start);
00326 start = std::string::npos;
00327 }
00328 result = bag.find(token);
00329 if (result != 0 )
00330 {
00331 result_bag = dynamic_cast<Property<PropertyBag>*>(result);
00332 if ( result_bag != 0 && start != std::string::npos ) {
00333 return findProperty( result_bag->rvalue(), nameSequence.substr( start ), separator );
00334 }
00335 else
00336 return result;
00337 }
00338 return 0;
00339 }
00340
00344 void listPropertiesHelper(const PropertyBag& source, const std::string& separator, const string& prefix, vector<string>& result)
00345 {
00346 PropertyBag::const_iterator it( source.getProperties().begin() );
00347 while ( it != source.getProperties().end() ) {
00348 Property<PropertyBag>* sub = dynamic_cast<Property<PropertyBag>*>(*it);
00349 string itemname = prefix.empty() ? (*it)->getName() : prefix + separator + (*it)->getName();
00350 result.push_back( itemname );
00351 if ( sub && sub->ready() ) {
00352 listPropertiesHelper( sub->value(), separator, itemname, result );
00353 }
00354 ++it;
00355 }
00356 }
00357
00360 void listDescriptionsHelper(const PropertyBag& source, const std::string& separator, vector<string>& result)
00361 {
00362 PropertyBag::const_iterator it( source.getProperties().begin() );
00363 while ( it != source.getProperties().end() ) {
00364 Property<PropertyBag>* sub = dynamic_cast<Property<PropertyBag>*>(*it);
00365 result.push_back( (*it)->getDescription() );
00366 if ( sub && sub->ready() ) {
00367 listDescriptionsHelper( sub->value(), separator, result );
00368 }
00369 ++it;
00370 }
00371 }
00374 vector<string> listProperties(const PropertyBag& source, const std::string& separator)
00375 {
00376 vector<string> result;
00377 listPropertiesHelper( source, separator, "", result);
00378 return result;
00379 }
00380
00381 vector<string> listPropertyDescriptions(const PropertyBag& source, const std::string& separator)
00382 {
00383 vector<string> result;
00384 listDescriptionsHelper( source, separator, result);
00385 return result;
00386 }
00387
00388 bool storeProperty(PropertyBag& bag, const std::string& path, base::PropertyBase* item, const std::string& separator )
00389 {
00390 Logger::In in("storeProperty");
00391 if ( path.empty() || path == separator )
00392 return bag.ownProperty( item );
00393
00394 string pname, rest;
00395 if ( path.find(separator) != string::npos ) {
00396 pname = path.substr( 0, path.find(separator));
00397 rest = path.substr( path.find(separator) + separator.length() );
00398 } else {
00399 pname = path;
00400 }
00401
00402 if ( pname.empty() && !rest.empty() )
00403 return storeProperty( bag, rest, item, separator);
00404
00405
00406 PropertyBase* parent = bag.find(pname);
00407 if (!parent) {
00408 bag.ownProperty( new Property<PropertyBag>(pname,"") );
00409 parent = bag.find(pname);
00410 }
00411 Property<PropertyBag>* parentbag = dynamic_cast<Property<PropertyBag>* >(parent);
00412 if ( !parentbag ) {
00413 log(Error) << "Path component '" << pname << "' in path '"<<path<<"' does not point to a PropertyBag."<<endlog();
00414 return false;
00415 }
00416
00417 return storeProperty( parentbag->value(), rest, item, separator);
00418 }
00419
00420 bool removeProperty(PropertyBag& bag, const std::string& path, const std::string& separator )
00421 {
00422
00423 if ( path.empty() || path == separator )
00424 return false;
00425
00426 if ( path.find( separator ) == string::npos)
00427 return bag.removeProperty( bag.find(path) );
00428
00429 string prefix = path.substr( 0, path.rfind(separator));
00430 string pname = path.substr( path.rfind(separator) + separator.length() );
00431
00432 if ( prefix.empty() )
00433 return bag.removeProperty( bag.find(pname) );
00434
00435 Property<PropertyBag> parent = findProperty( bag, prefix);
00436 if ( !parent.ready() )
00437 return false;
00438 return parent.value().removeProperty( parent.value().find( pname ) );
00439 }
00440
00441 bool updateOrRefreshProperty( PropertyBase* source, PropertyBase* target, bool update)
00442 {
00443 #ifndef NDEBUG
00444 if (update)
00445 log(Debug) << "updateProperties: updating Property "
00446 << source->getType() << " "<< source->getName()
00447 << "." << endlog();
00448 else
00449 log(Debug) << "refreshProperties: refreshing Property "
00450 << source->getType() << " "<< source->getName()
00451 << "." << endlog();
00452 #endif
00453
00454 if ( (update && target->update( source ) == false ) || (!update && target->refresh( source ) == false ) ) {
00455
00456 DataSourceBase::shared_ptr converted = target->getTypeInfo()->convert( source->getDataSource() );
00457 if ( !converted || converted == source->getDataSource() ) {
00458
00459 converted = target->getDataSource();
00460 if (target->getTypeInfo()->composeType( source->getDataSource(), converted ) ) {
00461
00462 log(Debug) << "Composed Property "
00463 << target->getType() << " "<< source->getName() << " to type " <<target->getType()
00464 << " from type " << source->getType() << endlog();
00465 return true;
00466 } else {
00467
00468 log(Error) << (update ? "updateProperties: " : "refreshProperties: ") << " Could not update, nor convert Property "
00469 << target->getType() << " "<< target->getName()
00470 << ": type mismatch, can not update with "
00471 << source->getType() << " "<< source->getName() << endlog();
00472 return false;
00473 }
00474 } else {
00475
00476
00477
00478 PropertyBase* dummy = target->getTypeInfo()->buildProperty("","");
00479 dummy->getDataSource()->update( converted.get() );
00480 assert(dummy->getTypeInfo() == converted->getTypeInfo() );
00481
00482 if (update)
00483 target->update(dummy);
00484 else
00485 target->refresh(dummy);
00486 log(Debug) << "Converted Property "
00487 << target->getType() << " "<< source->getName() << " to type " <<dummy->getType()
00488 << " from type " << source->getType() << endlog();
00489 }
00490 }
00491 return true;
00492 }
00493
00494 bool refreshProperties(const PropertyBag& target, const PropertyBag& source, bool allprops)
00495 {
00496 Logger::In in("refreshProperties");
00497
00498
00499 if ( Types()->type(target.getType()) != Types()->getTypeInfo<PropertyBag>() && Types()->type( target.getType() ) != Types()->type( source.getType() ) ) {
00500 log(Error) << "Can not populate typed PropertyBag '"<< target.getType() <<"' from '"<<source.getType()<<"' (source and target type differed)."<<endlog();
00501 return false;
00502 }
00503
00504
00505 PropertyBag::const_iterator it( target.getProperties().begin() );
00506 bool failure = false;
00507 while ( it != target.getProperties().end() )
00508 {
00509 PropertyBase* srcprop;
00510 if ( (*it)->getName() == "" )
00511 srcprop = source.getItem( it - target.getProperties().begin() );
00512 else
00513 srcprop = source.find( (*it)->getName() );
00514 PropertyBase* tgtprop = *it;
00515 if (srcprop != 0)
00516 {
00517 if (updateOrRefreshProperty( srcprop, tgtprop, false) == false)
00518 return false;
00519
00520 } else if (allprops) {
00521 log(Error) << "Could not find Property "
00522 << tgtprop->getType() << " "<< tgtprop->getName()
00523 << " in source."<< endlog();
00524 failure = true;
00525 }
00526 ++it;
00527 }
00528 return !failure;
00529 }
00530
00531 bool refreshProperty(const PropertyBag& target, const PropertyBase& source)
00532 {
00533 PropertyBase* target_prop;
00534
00535 if ( 0 != (target_prop = target.find( source.getName() ) ) )
00536 {
00537 return target_prop->refresh( &source );
00538 }
00539 return false;
00540 }
00541
00542 bool copyProperties(PropertyBag& target, const PropertyBag& source)
00543 {
00544
00545
00546 PropertyBag::const_iterator it( source.getProperties().begin() );
00547 while ( it != source.getProperties().end() )
00548 {
00549
00550 PropertyBase* temp = (*it)->create();
00551
00552 temp->copy( *it );
00553
00554 target.add( temp );
00555 ++it;
00556 }
00557 return true;
00558 }
00559
00560
00561 bool updateProperties(PropertyBag& target, const PropertyBag& source)
00562 {
00563
00564 if ( target.getType() == "" || target.getType() == "type_less" )
00565 target.setType("PropertyBag");
00566
00567
00568 if ( Types()->type( target.getType() ) != Types()->getTypeInfo<PropertyBag>() && Types()->type(target.getType()) != Types()->type(source.getType()) ) {
00569 log(Error) << "Can not populate typed PropertyBag '"<< target.getType() <<"' from '"<<source.getType()<<"' (source and target type differed)."<<endlog();
00570 return false;
00571 }
00572
00573 target.setType( source.getType() );
00574
00575
00576
00577
00578 PropertyBag::Names allnames = source.list();
00579 PropertyBag::Names::const_iterator endnames = std::unique(allnames.begin(), allnames.end());
00580 PropertyBag::Names::const_iterator it( allnames.begin() );
00581 while ( it != endnames )
00582 {
00583 PropertyBag::Properties sources = source.getProperties(*it);
00584 PropertyBag::Properties mines = target.getProperties(*it);
00585 PropertyBag::iterator mit = mines.begin();
00586 for( PropertyBag::const_iterator sit = sources.begin(); sit != sources.end(); ++sit ) {
00587 if ( mit != mines.end() ) {
00588 assert( (*sit)->getName() == (*mit)->getName());
00589 if ( updateOrRefreshProperty( *sit, *mit, true) == false)
00590 return false;
00591
00592 ++mit;
00593 }
00594 else
00595 {
00596 #ifndef NDEBUG
00597 Logger::log() << Logger::Debug;
00598 Logger::log() << "updateProperties: creating Property "
00599 << (*sit)->getType() << " "<< (*sit)->getName()
00600 << "." << Logger::endl;
00601 #endif
00602
00603 PropertyBase* temp = 0;
00604 #if 0
00605 Property<PropertyBag>* tester = dynamic_cast<Property<PropertyBag>* >(*sit);
00606 if (tester && Types()->type( tester->value().getType() ) != Types()->getTypeInfo<PropertyBag>()) {
00607 if (TypeInfo* ti = types::Types()->type(tester->value().getType())) {
00608 temp = ti->buildProperty( tester->getName(), tester->getDescription() );
00609 assert(temp);
00610 bool res = temp->getTypeInfo()->composeType( tester->getDataSource(), temp->getDataSource() );
00611 if (!res ) return false;
00612 }
00613 }
00614 #endif
00615 if (!temp) {
00616
00617 temp = (*sit)->create();
00618
00619 temp->update( (*sit) );
00620 }
00621
00622 target.add( temp );
00623 }
00624 }
00625 ++it;
00626 }
00627 return true;
00628 }
00629
00630 bool updateProperty(PropertyBag& target, const PropertyBag& source, const std::string& name, const std::string& separator)
00631 {
00632 Logger::In in("updateProperty");
00633
00634 PropertyBase* source_walker;
00635 PropertyBase* target_walker;
00636 std::string token;
00637 std::string::size_type start = 0;
00638 if ( separator.length() != 0 && name.find(separator) == 0 )
00639 start = separator.length();
00640 std::string::size_type len = name.find(separator, start);
00641 if (len != std::string::npos) {
00642 token = name.substr(start,len-start);
00643 start = len + separator.length();
00644 if ( start >= name.length() )
00645 start = std::string::npos;
00646 }
00647 else {
00648 token = name.substr(start);
00649 start = std::string::npos;
00650 }
00651 source_walker = source.find(token);
00652 target_walker = target.find(token);
00653 if (source_walker != 0 )
00654 {
00655 if ( target_walker == 0 ) {
00656
00657 target_walker = source_walker->create();
00658 target.ownProperty( target_walker );
00659 }
00660 Property<PropertyBag>* source_walker_bag;
00661 Property<PropertyBag>* target_walker_bag;
00662 source_walker_bag = dynamic_cast<Property<PropertyBag>*>(source_walker);
00663 target_walker_bag = dynamic_cast<Property<PropertyBag>*>(target_walker);
00664 if ( source_walker_bag != 0 && start != std::string::npos ) {
00665 if ( target_walker_bag == 0 ) {
00666 log(Error) << "Property '"<<target_walker->getName()<<"' is not a PropertyBag !"<<endlog();
00667 return false;
00668 }
00669 return updateProperty( target_walker_bag->value(), source_walker_bag->rvalue(), name.substr( start ), separator );
00670 }
00671 else {
00672
00673 if (updateOrRefreshProperty( source_walker, target_walker, true) == false)
00674 return false;
00675 log(Debug) << "Found Property '"<<target_walker->getName() <<"': update done." << endlog();
00676 return true;
00677 }
00678 } else {
00679
00680 log(Error) << "Property '"<< token <<"' is not present in the source PropertyBag !"<<endlog();
00681 return false;
00682 }
00683
00684 return false;
00685 }
00686
00687 bool refreshProperty(PropertyBag& target, const PropertyBag& source, const std::string& name, const std::string& separator)
00688 {
00689 Logger::In in("refreshProperty");
00690
00691 PropertyBase* source_walker;
00692 PropertyBase* target_walker;
00693 std::string token;
00694 std::string::size_type start = 0;
00695 if ( separator.length() != 0 && name.find(separator) == 0 )
00696 start = separator.length();
00697 std::string::size_type len = name.find(separator, start);
00698 if (len != std::string::npos) {
00699 token = name.substr(start,len-start);
00700 start = len + separator.length();
00701 if ( start >= name.length() )
00702 start = std::string::npos;
00703 }
00704 else {
00705 token = name.substr(start);
00706 start = std::string::npos;
00707 }
00708 source_walker = source.find(token);
00709 target_walker = target.find(token);
00710 if (source_walker != 0 )
00711 {
00712 if ( target_walker == 0 ) {
00713 log(Error) << "Property '"<<source_walker->getName()<<"' was not found in target !"<<endlog();
00714 return false;
00715 }
00716 Property<PropertyBag>* source_walker_bag;
00717 Property<PropertyBag>* target_walker_bag;
00718 source_walker_bag = dynamic_cast<Property<PropertyBag>*>(source_walker);
00719 target_walker_bag = dynamic_cast<Property<PropertyBag>*>(target_walker);
00720 if ( source_walker_bag != 0 && start != std::string::npos ) {
00721 if ( target_walker_bag == 0 ) {
00722 log(Error) << "Property '"<<target_walker->getName()<<"' is not a PropertyBag !"<<endlog();
00723 return false;
00724 }
00725 return refreshProperty( target_walker_bag->value(), source_walker_bag->rvalue(), name.substr( start ), separator );
00726 }
00727 else {
00728 if (updateOrRefreshProperty( source_walker, target_walker, false) == false)
00729 return false;
00730 log(Debug) << "Found Property '"<<target_walker->getName() <<"': refresh done." << endlog();
00731 return true;
00732 }
00733 } else {
00734
00735 log(Error) << "Property '"<< token <<"' is not present in the source PropertyBag !"<<endlog();
00736 return false;
00737 }
00738
00739 return false;
00740 }
00741
00742 void deleteProperties(PropertyBag& target)
00743 {
00744
00745 PropertyBag::const_iterator it( target.getProperties().begin() );
00746 while ( it != target.getProperties().end() )
00747 {
00748
00749 if (!target.ownsProperty( *it ))
00750 delete (*it);
00751 ++it;
00752 }
00753 target.clear();
00754 }
00755
00756 void deletePropertyBag(PropertyBag& target)
00757 {
00758
00759 PropertyBag::const_iterator it( target.getProperties().begin() );
00760 while ( it != target.getProperties().end() )
00761 {
00762
00763 Property<PropertyBag>* result = dynamic_cast< Property<PropertyBag>* >( *it );
00764 if ( result != 0 )
00765 deletePropertyBag( result->value() );
00766 if (!target.ownsProperty( *it ))
00767 delete (*it);
00768 ++it;
00769 }
00770
00771 target.clear();
00772 }
00773
00774 void flattenPropertyBag(PropertyBag& target, const std::string& separator)
00775 {
00776
00777 Property<PropertyBag>* result;
00778 PropertyBag::const_iterator it( target.getProperties().begin() );
00779 while ( it != target.getProperties().end() )
00780 {
00781 result = dynamic_cast< Property<PropertyBag>* >( *it );
00782 if ( result != 0 )
00783 {
00784 flattenPropertyBag( result->value(), separator );
00785
00786 PropertyBag::const_iterator flat_it( result->value().getProperties().begin() ) ;
00787 if ( flat_it != result->value().getProperties().end() )
00788 {
00789 while (flat_it != result->value().getProperties().end() )
00790 {
00791 (*flat_it)->setName( result->getName() + separator + (*flat_it)->getName() );
00792 target.add( (*flat_it) );
00793 result->value().remove( *flat_it );
00794 flat_it = result->value().getProperties().begin();
00795 }
00796 it = target.getProperties().begin();
00797 continue;
00798 }
00799
00800 }
00801 ++it;
00802 }
00803 }
00804
00805 }