Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

Config.cxx

Go to the documentation of this file.
00001 
00002 // $Id: Config.cxx,v 1.3 2009/01/06 20:41:27 fmwk Exp $
00003 //
00005 //
00006 // messier@indiana.edu
00008 #include "Config/Config.h"
00009 #include <iomanip>
00010 #include <iostream>
00011 #include <sstream>
00012 #include "Config/Param.h"
00013 #include "Config/Table.h"
00014 
00017 static bool gsNoEdits        = false;
00018 static bool gsNoDefaultEdits = true;
00019 static bool gsAllEditOK      = false;
00020 
00021 //......................................................................
00022 
00023 void cfg::Config::SetEditAllOK() { gsAllEditOK = true; }
00024 
00025 //......................................................................
00026 
00027 cfg::Config::Config(const char* name, 
00028                     const char* version, 
00029                     const char* source) : 
00030   fEditable( true    ),
00031   fName    ( name    ),
00032   fVersion ( version ),
00033   fSource  ( source  )
00034 { }
00035 
00036 //......................................................................
00037 
00038 cfg::Config::~Config() { fEditable = true; this->RemoveParam("*"); }
00039 
00040 //......................................................................
00041 
00042 const char* cfg::Config::GetName() const { return fName.c_str(); }
00043 
00044 //......................................................................
00045 
00046 const char* cfg::Config::GetVersion() const { return fVersion.c_str(); }
00047 
00048 //......................................................................
00049 
00050 const char* cfg::Config::GetSource() const { return fSource.c_str(); }
00051 
00052 //......................................................................
00053 
00054 bool cfg::Config::IsEditable() const { return fEditable; }
00055 
00056 //......................................................................
00057 
00058 const cfg::Param& cfg::Config::operator()(const char* pname) const 
00059 {
00060 //======================================================================
00061 // Allows read-only access to parameters
00062 //======================================================================
00063   cfg::Config::ParamMap::iterator itr = fParam.find(pname);
00064   if (itr==fParam.end()) {
00065     throw cfg::Exception(cfg::Exception::kParamNotFound,
00066                          pname, 
00067                          __FILE__,
00068                          __LINE__);
00069   }
00070   return (*itr->second);
00071 }
00072 
00073 //......................................................................
00074 
00075 const cfg::Param& cfg::Config::operator()(const std::string& pname) const
00076 {
00077 //======================================================================
00078 // Allows read-only access to parameters
00079 //======================================================================
00080   cfg::Config::ParamMap::iterator itr = fParam.find(pname);
00081   if (itr==fParam.end()) {
00082     std::ostringstream os;
00083     os << "Parameter " << pname    << " not found in configuration " 
00084        << fName << ":" << fVersion << std::endl;
00085     throw cfg::Exception(cfg::Exception::kParamNotFound,
00086                          os.str().c_str(),
00087                          __FILE__,
00088                          __LINE__);
00089   }
00090   return (*itr->second);
00091 }
00092 
00093 //......................................................................
00094 
00095 cfg::Param& cfg::Config::Par(const char* pname) 
00096 {
00097 //======================================================================
00098 // Allows non-const access to parameters
00099 //======================================================================
00100   this->EditOK();
00101   std::string p(pname);
00102   cfg::Config::ParamMap::iterator itr = fParam.find(p);
00103   if (itr==fParam.end()) {
00104     std::ostringstream os;
00105     os << "Parameter " << pname    << " not found in configuration " 
00106        << fName << ":" << fVersion << std::endl;
00107     throw cfg::Exception(cfg::Exception::kParamNotFound,
00108                          os.str().c_str(),
00109                          __FILE__,
00110                          __LINE__);
00111   }
00112   return (*itr->second);
00113 }
00114 
00115 //......................................................................
00116 
00117 cfg::Param& cfg::Config::Par(const std::string& pname)
00118 {
00119 //======================================================================
00120 // Allows non-const access to parameters
00121 //======================================================================
00122   this->EditOK();
00123   cfg::Config::ParamMap::iterator itr = fParam.find(pname);
00124   if (itr==fParam.end()) {
00125     std::ostringstream os;
00126     os << "Parameter " << pname    << " not found in configuration " 
00127        << fName << ":" << fVersion << std::endl;
00128     throw cfg::Exception(cfg::Exception::kParamNotFound,
00129                          os.str().c_str(),
00130                          __FILE__,
00131                          __LINE__);
00132   }
00133   return (*itr->second);
00134 }
00135 
00136 //......................................................................
00137 
00138 bool cfg::Config::EditOK() const 
00139 {
00140 //======================================================================
00141 // Check if it is OK to edit this configuration. Throws exception is
00142 // edit is not allowed
00143 //======================================================================
00144   if (gsAllEditOK) return true;
00145   if (fEditable==false) {
00146     std::ostringstream os;
00147     os << "Attempt to get read access to read-only config "
00148        << "." << this->GetVersion();
00149     throw cfg::Exception(cfg::Exception::kConfigRO,
00150                          os.str().c_str(),
00151                          __FILE__,
00152                          __LINE__);
00153   }
00154   return fEditable;
00155 }
00156 
00157 //......................................................................
00158 
00159 void cfg::Config::SetReadOnly(int flag) 
00160 {
00161 //======================================================================
00162 // Set the read-only status for this configuration.
00163 //   flag =  0 - allow read/write access
00164 //   flag =  1 - read only access
00165 //   flag = -1 - determine read/write accees based on R/W policies for
00166 //               configurations
00167 //======================================================================
00168   if (flag == 1 && fEditable == false) return; // RO already
00169   
00170   // First make sure we are allowed to change the state. Once set read
00171   // only the configuration is always read only
00172   this->EditOK();
00173 
00174   if (flag ==  0) { fEditable = true;  return; } // RW
00175   if (flag ==  1) { fEditable = false; return; } // RO
00176 
00177   // Apply policy to determine RW status
00178   
00179   // Edits turned off globally
00180   if (gsNoEdits == true) { fEditable = false; return; } // RO
00181   
00182   // Edits turned off globally for default configurations
00183   if ( (gsNoDefaultEdits == true) && (this->fVersion == "default") ) {
00184     fEditable = false; // RO
00185     return;
00186   }
00187   
00188   // Edit allowed
00189   fEditable = true; // RW
00190 }
00191 
00192 //......................................................................
00193 
00194 void cfg::Config::SetSource(const char* filename) { fSource = filename; }
00195 
00196 //......................................................................
00197 
00198 void cfg::Config::AdoptParam(cfg::Param* p) 
00199 {
00200 //======================================================================
00201 // Insert the parameter p into a configuration. If the parameter
00202 // already exists in the configuration then replace it. Ownership of
00203 // the parameter stored at p is transferred to the configuration.
00204 //======================================================================
00205   this->EditOK();
00206   
00207   std::string s = p->GetName();
00208   
00209   // Check the parameter set for one of this name. If one is found
00210   // replace it
00211   cfg::Param* param = fParam[s];
00212   if (param==0) delete param;
00213   
00214   fParam[s] = p;
00215 }
00216 
00217 //......................................................................
00218 
00219 void cfg::Config::RemoveParam(const char* which) 
00220 {
00221 //======================================================================
00222 // Remove a selected parameter from the configuration. "*" removes all
00223 // parameters
00224 //======================================================================
00225   this->EditOK();
00226 
00227   std::string s(which);
00228   // If which is "*" remove all parameters
00229   if (s=="*") {
00230     cfg::Config::ParamMap::iterator    itr(fParam.begin());
00231     cfg::Config::ParamMap::iterator itrEnd(fParam.end());
00232     for (; itr!=itrEnd; ++itr) {
00233       if (itr->second) { delete itr->second; itr->second = 0; }
00234     }
00235     return;
00236   }
00237   
00238   // Otherwise just remove the named set
00239   cfg::Param* param = fParam[s];
00240   if (param==0) { delete param; fParam[s] = 0; }
00241 }
00242 
00243 //......................................................................
00244 
00245 void cfg::Config::Copy(cfg::Config& dest, 
00246                        const cfg::Config& src,
00247                        const char* destVersion,
00248                        const char* destSource) 
00249 {
00250 //======================================================================
00251 // Copy one configuration to another
00252 //   dest - configuration to copy to
00253 //   src  - configuration to copy from
00254 //   destVersion - version tag appied to dest (default appends '.copy')
00255 //   destSource  - source tag appied to dest (default appends '(copy)' )
00256 //======================================================================
00257   dest.EditOK();
00258 
00259   dest.fName = src.fName;
00260   if (destVersion==0) { 
00261     dest.fVersion  = src.fVersion;
00262     dest.fVersion += ".copy";
00263   }
00264   else {
00265     dest.fVersion = destVersion;
00266   }
00267   if (destSource==0) {
00268     dest.fSource  = src.fSource;
00269     dest.fSource += "(copy)";
00270   }
00271   else {
00272     dest.fSource = destSource;
00273   }
00274 
00275   // Wipe the parameter map clean and build a new one using the cfg::Param
00276   // copy constructor on each element in the source map
00277   dest.RemoveParam("*");
00278   cfg::Config::ParamMap::const_iterator    itr(src.fParam.begin());
00279   cfg::Config::ParamMap::const_iterator itrEnd(src.fParam.end());
00280   for (; itr!=itrEnd; ++itr) {
00281     cfg::Param* p = new cfg::Param(*itr->second);
00282     dest.AdoptParam(p);
00283   }
00284 }
00285 
00286 //......................................................................
00287 
00291 std::string cfg::Config::AsXML() const 
00292 {
00293   // I'm not too excited about the need for "setprecision(8)" below,
00294   // but without it you seem to either lose precision with doubles and
00295   // floats or to gain bogus digits. The number 8 is fairly fine tuned
00296   // which is why I'm not excited -- I'd rather have something more
00297   // robust. Such is life I suppose.
00298   std::ostringstream xml;
00299   xml << "<config name=\"" << this->fName 
00300       << "\" version=\"" << this->fVersion << "\">\n";
00301   ParamMap::const_iterator itr(fParam.begin());
00302   ParamMap::const_iterator itrEnd(fParam.end());
00303   for (; itr!=itrEnd; ++itr) {
00304     const cfg::Param* p = itr->second;
00305     xml << "  <param name=\"" << p->GetName() << "\">\n"
00306         << "    <" << p->XMLTag() << "> "
00307         << std::setprecision(8) << (*p)
00308         << " </" << p->XMLTag() << ">\n";
00309     xml << "    " << p->GetComment() << "\n";
00310     xml << "  </param>\n";
00311   }
00312   xml << "</config>\n";
00313   return xml.str();
00314 }
00315 

Generated on Sat Nov 7 04:46:56 2009 for NOvA Offline by  doxygen 1.3.9.1