Orocos Real-Time Toolkit
2.6.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 PropertyLoader::PropertyLoader(TaskContext *task) 00057 : target(task->provides().get()) 00058 {} 00059 00060 PropertyLoader::PropertyLoader(Service *service) 00061 : target(service) 00062 {} 00063 00064 bool PropertyLoader::load(const std::string& filename) const 00065 { 00066 Logger::In in("PropertyLoader:load"); 00067 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00068 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00069 return false; 00070 00071 #else 00072 if ( target->properties() == 0) { 00073 log(Error) << "Service " <<target->getName()<<" has no Properties to configure." << endlog(); 00074 return false; 00075 } 00076 00077 log(Info) << "Loading properties into Service '" <<target->getName() 00078 <<"' with '"<<filename<<"'."<< endlog(); 00079 bool failure = false; 00080 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00081 try 00082 { 00083 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00084 } catch (...) { 00085 log(Error) << "Could not open file "<< filename << endlog(); 00086 return false; 00087 } 00088 try { 00089 PropertyBag propbag; 00090 vector<ActionInterface*> assignComs; 00091 00092 if ( demarshaller->deserialize( propbag ) ) 00093 { 00094 // compose propbag: 00095 PropertyBag composed_props; 00096 if ( composePropertyBag(propbag, composed_props) == false) { 00097 delete demarshaller; 00098 return false; 00099 } 00100 // take restore-copy; 00101 PropertyBag backup; 00102 copyProperties( backup, *target->properties() ); 00103 // First test if the updateProperties will succeed: 00104 if ( refreshProperties( *target->properties(), composed_props, false) ) { // not strict 00105 // this just adds the new properties, *should* never fail, but 00106 // let's record failure to be sure. 00107 failure = !updateProperties( *target->properties(), composed_props ); 00108 } else { 00109 // restore backup in case of failure: 00110 refreshProperties( *target->properties(), backup, false ); // not strict 00111 failure = true; 00112 } 00113 // cleanup 00114 deletePropertyBag( backup ); 00115 } 00116 else 00117 { 00118 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00119 failure = true; 00120 } 00121 } catch (...) 00122 { 00123 log(Error) 00124 << "Uncaught exception in deserialise !"<< endlog(); 00125 failure = true; 00126 } 00127 delete demarshaller; 00128 return !failure; 00129 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00130 00131 } 00132 00133 bool PropertyLoader::configure(const std::string& filename, bool all ) const 00134 { 00135 Logger::In in("PropertyLoader:configure"); 00136 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00137 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00138 return false; 00139 00140 #else 00141 if ( target->properties() == 0) { 00142 log(Error) << "Service " <<target->getName()<<" has no Properties to configure." << endlog(); 00143 return false; 00144 } 00145 00146 log(Info) << "Configuring Service '" <<target->getName() 00147 <<"' with '"<<filename<<"'."<< endlog(); 00148 bool failure = false; 00149 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00150 try 00151 { 00152 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00153 } catch (...) { 00154 log(Error) << "Could not open file "<< filename << endlog(); 00155 return false; 00156 } 00157 try { 00158 PropertyBag propbag; 00159 00160 if ( demarshaller->deserialize( propbag ) ) 00161 { 00162 // compose propbag: 00163 PropertyBag composed_props; 00164 if ( composePropertyBag(propbag, composed_props) == false) { 00165 delete demarshaller; 00166 return false; 00167 } 00168 // take restore-copy; 00169 PropertyBag backup; 00170 copyProperties( backup, *target->properties() ); 00171 if ( refreshProperties( *target->properties(), composed_props, all ) == false ) { 00172 // restore backup: 00173 refreshProperties( *target->properties(), backup ); 00174 failure = true; 00175 } 00176 // cleanup 00177 deletePropertyBag( backup ); 00178 } 00179 else 00180 { 00181 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00182 failure = true; 00183 } 00184 deletePropertyBag( propbag ); 00185 } catch (...) 00186 { 00187 log(Error) 00188 << "Uncaught exception in deserialise !"<< endlog(); 00189 failure = true; 00190 } 00191 delete demarshaller; 00192 return !failure; 00193 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00194 00195 } 00196 00197 bool PropertyLoader::store(const std::string& filename) const 00198 { 00199 Logger::In in("PropertyLoader::store"); 00200 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00201 log(Error) << "No Property Marshaller configured !" << endlog(); 00202 return false; 00203 #else 00204 std::ofstream file( filename.c_str() ); 00205 if ( file ) 00206 { 00207 // Write results 00208 PropertyBag* compProps = target->properties(); 00209 PropertyBag allProps; 00210 00211 // decompose repos into primitive property types. 00212 PropertyBagIntrospector pbi( allProps ); 00213 pbi.introspect( *compProps ); 00214 00215 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00216 marshaller.serialize( allProps ); 00217 deletePropertyBag( allProps ); 00218 log(Info) << "Wrote "<< filename <<endlog(); 00219 } 00220 else { 00221 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00222 return false; 00223 } 00224 return true; 00225 #endif 00226 } 00227 00228 bool PropertyLoader::save(const std::string& filename, bool all) const 00229 { 00230 Logger::In in("PropertyLoader::save"); 00231 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00232 log(Error) << "No Property MarshallInterface configured !" << endlog(); 00233 return false; 00234 00235 #else 00236 if ( target->properties() == 0 ) { 00237 log(Error) << "Service "<< target->getName() 00238 << " does not have Properties to save." << endlog(); 00239 return false; 00240 } 00241 PropertyBag allProps; 00242 PropertyBag decompProps; 00243 00244 // first check if the target file exists. 00245 std::ifstream ifile( filename.c_str() ); 00246 // if target file does not exist, skip this step. 00247 if ( ifile ) { 00248 ifile.close(); 00249 log(Info) << target->getName()<<" updating of file "<< filename << endlog(); 00250 // The demarshaller itself will open the file. 00251 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER demarshaller( filename ); 00252 if ( demarshaller.deserialize( allProps ) == false ) { 00253 // Parse error, abort writing of this file. 00254 log(Error) << "While updating "<< target->getName() <<" : Failed to read "<< filename << endlog(); 00255 return false; 00256 } 00257 } 00258 else { 00259 log(Info) << "Creating "<< filename << endlog(); 00260 return store(filename); 00261 } 00262 00263 // Write results 00264 PropertyBag* compProps = target->properties(); 00265 00266 // decompose repos into primitive property types. 00267 PropertyBagIntrospector pbi( decompProps ); 00268 pbi.introspect( *compProps ); 00269 00270 //Add target properties to existing properties 00271 bool updater = false; 00272 if (all) { 00273 log(Info) << "Writing all properties of "<<target->getName()<<" to file "<< filename << endlog(); 00274 updater = updateProperties( allProps, decompProps ); // add new. 00275 } 00276 else { 00277 log(Info) << "Refreshing properties in file "<< filename << " with values of properties of "<<target->getName() << endlog(); 00278 updater = refreshProperties( allProps, decompProps ); // only refresh existing. 00279 } 00280 if (updater == false) { 00281 log(Error) << "Could not update properties of file "<< filename <<"."<<endlog(); 00282 deletePropertyBag( allProps ); 00283 deletePropertyBag( decompProps ); 00284 return false; 00285 } 00286 // ok, finish. 00287 // serialize and cleanup 00288 std::ofstream file( filename.c_str() ); 00289 if ( file ) 00290 { 00291 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00292 marshaller.serialize( allProps ); 00293 log(Info) << "Wrote "<< filename <<endlog(); 00294 } 00295 else { 00296 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00297 deletePropertyBag( allProps ); 00298 return false; 00299 } 00300 // allProps contains copies (clone()), thus may be safely deleted : 00301 deletePropertyBag( allProps ); 00302 deletePropertyBag( decompProps ); 00303 return true; 00304 #endif 00305 } 00306 00307 bool PropertyLoader::configure(const std::string& filename, const std::string& name ) const 00308 { 00309 Logger::In in("PropertyLoader:configure"); 00310 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00311 log(Error) << "No Property DemarshallInterface configured !" << endlog(); 00312 return false; 00313 00314 #else 00315 log(Info) << "Reading Property '" <<name 00316 <<"' from file '"<<filename<<"'."<< endlog(); 00317 bool failure = false; 00318 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER* demarshaller = 0; 00319 try 00320 { 00321 demarshaller = new OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER (filename); 00322 } catch (...) { 00323 log(Error) << "Could not open file "<< filename << endlog(); 00324 return false; 00325 } 00326 try { 00327 PropertyBag propbag; 00328 if ( demarshaller->deserialize( propbag ) ) 00329 { 00330 // compose propbag: 00331 PropertyBag composed_props; 00332 if ( composePropertyBag(propbag, composed_props) == false) { 00333 deletePropertyBag( propbag ); 00334 delete demarshaller; 00335 return false; 00336 } 00337 failure = !refreshProperty( *(target->properties()), composed_props, name ); 00338 } 00339 else 00340 { 00341 log(Error) << "Some error occured while parsing "<< filename.c_str() <<endlog(); 00342 failure = true; 00343 } 00344 deletePropertyBag( propbag ); 00345 } catch (...) 00346 { 00347 log(Error) << "Uncaught exception in deserialise !"<< endlog(); 00348 failure = true; 00349 } 00350 delete demarshaller; 00351 return !failure; 00352 #endif // OROPKG_CORELIB_PROPERTIES_MARSHALLING 00353 } 00354 00355 bool PropertyLoader::save(const std::string& filename, const std::string& name) const 00356 { 00357 Logger::In in("PropertyLoader::save"); 00358 #ifndef OROPKG_CORELIB_PROPERTIES_MARSHALLING 00359 log(Error) << "No Property MarshallInterface configured !" << endlog(); 00360 return false; 00361 00362 #else 00363 PropertyBag fileProps; 00364 // Update exising file ? 00365 { 00366 // first check if the target file exists. 00367 std::ifstream ifile( filename.c_str() ); 00368 // if target file does not exist, skip this step. 00369 if ( ifile ) { 00370 ifile.close(); 00371 log(Info) << "Updating file "<< filename << " with properties of "<<target->getName()<<endlog(); 00372 // The demarshaller itself will open the file. 00373 OROCLS_CORELIB_PROPERTIES_DEMARSHALLING_DRIVER demarshaller( filename ); 00374 if ( demarshaller.deserialize( fileProps ) == false ) { 00375 // Parse error, abort writing of this file. 00376 log(Error) << "Failed to read "<< filename << endlog(); 00377 return false; 00378 } 00379 } 00380 else 00381 log(Info) << "Creating "<< filename << endlog(); 00382 } 00383 00384 // decompose service properties into primitive property types. 00385 PropertyBag serviceProps; 00386 PropertyBagIntrospector pbi( serviceProps ); 00387 pbi.introspect( *(target->properties()) ); 00388 00389 bool failure; 00390 failure = ! updateProperty( fileProps, serviceProps, name ); 00391 00392 deletePropertyBag( serviceProps ); 00393 00394 if ( failure ) { 00395 log(Error) << "Could not update properties of file "<< filename <<"."<<endlog(); 00396 deletePropertyBag( fileProps ); 00397 return false; 00398 } 00399 // serialize and cleanup 00400 std::ofstream file( filename.c_str() ); 00401 if ( file ) 00402 { 00403 OROCLS_CORELIB_PROPERTIES_MARSHALLING_DRIVER<std::ostream> marshaller( file ); 00404 marshaller.serialize( fileProps ); 00405 log(Info) << "Wrote Property "<<name <<" to "<< filename <<endlog(); 00406 } 00407 else { 00408 log(Error) << "Could not open file "<< filename <<" for writing."<<endlog(); 00409 deletePropertyBag( fileProps ); 00410 return false; 00411 } 00412 // fileProps contains copies (clone()), thus may be safely deleted : 00413 deletePropertyBag( fileProps ); 00414 return true; 00415 #endif 00416 } 00417