Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Sat May 7 12:56:52 CEST 2005 PropertyLoader.cxx 00003 00004 PropertyLoader.cxx - description 00005 ------------------- 00006 begin : Sat May 07 2005 00007 copyright : (C) 2005 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 00040 #include "PropertyLoader.hpp" 00041 #include "rtt-config.h" 00042 #ifdef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00043 #include ORODAT_CORELIB_PROPERTIES_MARSHALLING_INCLUDE 00044 #include ORODAT_CORELIB_PROPERTIES_DEMARSHALLING_INCLUDE 00045 #endif 00046 #include "../Logger.hpp" 00047 #include "../TaskContext.hpp" 00048 #include "PropertyBagIntrospector.hpp" 00049 #include "../types/PropertyComposition.hpp" 00050 #include <fstream> 00051 00052 using namespace std; 00053 using namespace RTT; 00054 using namespace RTT::detail; 00055 00056 bool PropertyLoader::load(const std::string& filename, TaskContext* target) const 00057 { 00058 Logger::In in("PropertyLoader:load"); 00059 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00060 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00061 return false; 00062 00063 #else 00064 if ( target->provides()->properties() == 0) { 00065 log(Error) << "TaskContext " <<target->getName()<<" has no Properties to configure." << endlog(); 00066 return false; 00067 } 00068 00069 log(Info) << "Loading properties into TaskContext '" <<target->getName() 00070 <<"' with '"<<filename<<"'."<< endlog(); 00071 bool failure = false; 00072 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00073 try 00074 { 00075 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00076 } catch (...) { 00077 log(Error) << "Could not open file "<< filename << endlog(); 00078 return false; 00079 } 00080 try { 00081 PropertyBag propbag; 00082 vector<ActionInterface*> assignComs; 00083 00084 if ( demarshaller->deserialize( propbag ) ) 00085 { 00086 // compose propbag: 00087 PropertyBag composed_props; 00088 if ( composePropertyBag(propbag, composed_props) == false) { 00089 delete demarshaller; 00090 return false; 00091 } 00092 // take restore-copy; 00093 PropertyBag backup; 00094 copyProperties( backup, *target->provides()->properties() ); 00095 // First test if the updateProperties will succeed: 00096 if ( refreshProperties( *target->provides()->properties(), composed_props, false) ) { // not strict 00097 // this just adds the new properties, *should* never fail, but 00098 // let's record failure to be sure. 00099 failure = !updateProperties( *target->provides()->properties(), composed_props ); 00100 } else { 00101 // restore backup in case of failure: 00102 refreshProperties( *target->provides()->properties(), backup, false ); // not strict 00103 failure = true; 00104 } 00105 // cleanup 00106 deletePropertyBag( backup ); 00107 } 00108 else 00109 { 00110 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00111 failure = true; 00112 } 00113 } catch (...) 00114 { 00115 log(Error) 00116 << "Uncaught exception in deserialise !"<< endlog(); 00117 failure = true; 00118 } 00119 delete demarshaller; 00120 return !failure; 00121 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00122 00123 } 00124 00125 bool PropertyLoader::configure(const std::string& filename, TaskContext* target, bool all ) const 00126 { 00127 Logger::In in("PropertyLoader:configure"); 00128 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00129 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00130 return false; 00131 00132 #else 00133 if ( target->provides()->properties() == 0) { 00134 log(Error) << "TaskContext " <<target->getName()<<" has no Properties to configure." << endlog(); 00135 return false; 00136 } 00137 00138 log(Info) << "Configuring TaskContext '" <<target->getName() 00139 <<"' with '"<<filename<<"'."<< endlog(); 00140 bool failure = false; 00141 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00142 try 00143 { 00144 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00145 } catch (...) { 00146 log(Error) << "Could not open file "<< filename << endlog(); 00147 return false; 00148 } 00149 try { 00150 PropertyBag propbag; 00151 00152 if ( demarshaller->deserialize( propbag ) ) 00153 { 00154 // compose propbag: 00155 PropertyBag composed_props; 00156 if ( composePropertyBag(propbag, composed_props) == false) { 00157 delete demarshaller; 00158 return false; 00159 } 00160 // take restore-copy; 00161 PropertyBag backup; 00162 copyProperties( backup, *target->provides()->properties() ); 00163 if ( refreshProperties( *target->provides()->properties(), composed_props, all ) == false ) { 00164 // restore backup: 00165 refreshProperties( *target->provides()->properties(), backup ); 00166 failure = true; 00167 } 00168 // cleanup 00169 deletePropertyBag( backup ); 00170 } 00171 else 00172 { 00173 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00174 failure = true; 00175 } 00176 deletePropertyBag( propbag ); 00177 } catch (...) 00178 { 00179 log(Error) 00180 << "Uncaught exception in deserialise !"<< endlog(); 00181 failure = true; 00182 } 00183 delete demarshaller; 00184 return !failure; 00185 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00186 00187 } 00188 00189 bool PropertyLoader::store(const std::string& filename, TaskContext* target) const 00190 { 00191 Logger::In in("PropertyLoader::store"); 00192 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00193 log(Error) << "No Property Marshaller configured !" << endlog(); 00194 return false; 00195 #else 00196 std::ofstream file( filename.c_str() ); 00197 if ( file ) 00198 { 00199 // Write results 00200 PropertyBag* compProps = target->properties(); 00201 PropertyBag allProps; 00202 00203 // decompose repos into primitive property types. 00204 PropertyBagIntrospector pbi( allProps ); 00205 pbi.introspect( *compProps ); 00206 00207 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00208 marshaller.serialize( allProps ); 00209 deletePropertyBag( allProps ); 00210 log(Info) << "Wrote "<< filename <<endlog(); 00211 } 00212 else { 00213 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00214 return false; 00215 } 00216 return true; 00217 #endif 00218 } 00219 00220 bool PropertyLoader::save(const std::string& filename, TaskContext* target, bool all) const 00221 { 00222 Logger::In in("PropertyLoader::save"); 00223 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00224 log(Error) << "No Property MarshallInterface configured !" << endlog(); 00225 return false; 00226 00227 #else 00228 if ( target->provides()->properties() == 0 ) { 00229 log(Error) << "TaskContext "<< target->getName() 00230 << " does not have Properties to save." << endlog(); 00231 return false; 00232 } 00233 PropertyBag allProps; 00234 PropertyBag decompProps; 00235 00236 // first check if the target file exists. 00237 std::ifstream ifile( filename.c_str() ); 00238 // if target file does not exist, skip this step. 00239 if ( ifile ) { 00240 ifile.close(); 00241 log(Info) << target->getName()<<" updating of file "<< filename << endlog(); 00242 // The demarshaller itself will open the file. 00243 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER demarshaller( filename ); 00244 if ( demarshaller.deserialize( allProps ) == false ) { 00245 // Parse error, abort writing of this file. 00246 log(Error) << "While updating "<< target->getName() <<" : Failed to read "<< filename << endlog(); 00247 return false; 00248 } 00249 } 00250 else { 00251 log(Info) << "Creating "<< filename << endlog(); 00252 return store(filename, target); 00253 } 00254 00255 // Write results 00256 PropertyBag* compProps = target->properties(); 00257 00258 // decompose repos into primitive property types. 00259 PropertyBagIntrospector pbi( decompProps ); 00260 pbi.introspect( *compProps ); 00261 00262 //Add target properties to existing properties 00263 bool updater = false; 00264 if (all) { 00265 log(Info) << "Writing all properties of "<<target->getName()<<" to file "<< filename << endlog(); 00266 updater = updateProperties( allProps, decompProps ); // add new. 00267 } 00268 else { 00269 log(Info) << "Refreshing properties in file "<< filename << " with values of properties of "<<target->getName() << endlog(); 00270 updater = refreshProperties( allProps, decompProps ); // only refresh existing. 00271 } 00272 if (updater == false) { 00273 log(Error) << "Could not update properties of file "<< filename <<"."<<endlog(); 00274 deletePropertyBag( allProps ); 00275 deletePropertyBag( decompProps ); 00276 return false; 00277 } 00278 // ok, finish. 00279 // serialize and cleanup 00280 std::ofstream file( filename.c_str() ); 00281 if ( file ) 00282 { 00283 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00284 marshaller.serialize( allProps ); 00285 log(Info) << "Wrote "<< filename <<endlog(); 00286 } 00287 else { 00288 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00289 deletePropertyBag( allProps ); 00290 return false; 00291 } 00292 // allProps contains copies (clone()), thus may be safely deleted : 00293 deletePropertyBag( allProps ); 00294 deletePropertyBag( decompProps ); 00295 return true; 00296 #endif 00297 } 00298 00299 bool PropertyLoader::configure(const std::string& filename, TaskContext* task, const std::string& name ) const 00300 { 00301 Logger::In in("PropertyLoader:configure"); 00302 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00303 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00304 return false; 00305 00306 #else 00307 log(Info) << "Reading Property '" <<name 00308 <<"' from file '"<<filename<<"'."<< endlog(); 00309 bool failure = false; 00310 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00311 try 00312 { 00313 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00314 } catch (...) { 00315 log(Error) << "Could not open file "<< filename << endlog(); 00316 return false; 00317 } 00318 try { 00319 PropertyBag propbag; 00320 if ( demarshaller->deserialize( propbag ) ) 00321 { 00322 // compose propbag: 00323 PropertyBag composed_props; 00324 if ( composePropertyBag(propbag, composed_props) == false) { 00325 deletePropertyBag( propbag ); 00326 delete demarshaller; 00327 return false; 00328 } 00329 failure = !refreshProperty( *(task->provides()->properties()), composed_props, name ); 00330 } 00331 else 00332 { 00333 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00334 failure = true; 00335 } 00336 deletePropertyBag( propbag ); 00337 } catch (...) 00338 { 00339 log(Error) << "Uncaught exception in deserialise !"<< endlog(); 00340 failure = true; 00341 } 00342 delete demarshaller; 00343 return !failure; 00344 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00345 } 00346 00347 bool PropertyLoader::save(const std::string& filename, TaskContext* task, const std::string& name) const 00348 { 00349 Logger::In in("PropertyLoader::save"); 00350 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00351 log(Error) << "No Property MarshallInterface configured !" << endlog(); 00352 return false; 00353 00354 #else 00355 PropertyBag fileProps; 00356 // Update exising file ? 00357 { 00358 // first check if the target file exists. 00359 std::ifstream ifile( filename.c_str() ); 00360 // if target file does not exist, skip this step. 00361 if ( ifile ) { 00362 ifile.close(); 00363 log(Info) << "Updating file "<< filename << " with properties of "<<task->getName()<<endlog(); 00364 // The demarshaller itself will open the file. 00365 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER demarshaller( filename ); 00366 if ( demarshaller.deserialize( fileProps ) == false ) { 00367 // Parse error, abort writing of this file. 00368 log(Error) << "Failed to read "<< filename << endlog(); 00369 return false; 00370 } 00371 } 00372 else 00373 log(Info) << "Creating "<< filename << endlog(); 00374 } 00375 00376 // decompose task properties into primitive property types. 00377 PropertyBag taskProps; 00378 PropertyBagIntrospector pbi( taskProps ); 00379 pbi.introspect( *(task->provides()->properties()) ); 00380 00381 bool failure; 00382 failure = ! updateProperty( fileProps, taskProps, name ); 00383 00384 deletePropertyBag( taskProps ); 00385 00386 if ( failure ) { 00387 log(Error) << "Could not update properties of file "<< filename <<"."<<endlog(); 00388 deletePropertyBag( fileProps ); 00389 return false; 00390 } 00391 // serialize and cleanup 00392 std::ofstream file( filename.c_str() ); 00393 if ( file ) 00394 { 00395 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00396 marshaller.serialize( fileProps ); 00397 log(Info) << "Wrote Property "<<name <<" to "<< filename <<endlog(); 00398 } 00399 else { 00400 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00401 deletePropertyBag( fileProps ); 00402 return false; 00403 } 00404 // fileProps contains copies (clone()), thus may be safely deleted : 00405 deletePropertyBag( fileProps ); 00406 return true; 00407 #endif 00408 } 00409