FesaException.cpp

Go to the documentation of this file.
00001 // Copyright CERN 2012 - Developed in collaboration with GSI
00002 
00003 #include <fesa-core/Exception/FesaException.h>
00004 
00005 #include <fesa-core/Core/AbstractEquipment.h>
00006 #include <fesa-core/Utilities/Lock.h>
00007 #include <fesa-core/Utilities/Mutex.h>
00008 #include <fesa-core/Utilities/ProcessConfiguration.h>
00009 #include <fesa-core/Utilities/StringUtilities.h>
00010 
00011 #include <cmw-log/Logger.h>
00012 
00013 #include <fstream>
00014 #include <set>
00015 #include <sstream>
00016 
00017 
00018 namespace
00019 {
00020 
00021 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.Exception.FesaException");
00022 
00026 static fesa::Mutex exceptionMutex;
00027 
00028 }
00029 
00030 
00031 namespace fesa
00032 {
00033 
00034 bool FesaException::messagesLoaded_ = false;
00035 std::map<std::string, std::string> FesaException::messages_;
00036 
00037 FesaException::FesaException() :
00038     errorCode_(""),
00039     file_(""),
00040     lineNumber_(-1)
00041 {
00042 }
00043 
00044 FesaException::FesaException(const std::string& file, int32_t lineNumber, const std::string& message) :
00045     message_(message),
00046     file_(file),
00047     lineNumber_(lineNumber)
00048 {
00049 }
00050 
00051 FesaException::FesaException(const std::string& file, int32_t lineNumber, const char* errorMessage, ...) :
00052     errorCode_(errorMessage),
00053     file_(file),
00054     lineNumber_(lineNumber)
00055 {
00056     va_list vl;
00057     va_start(vl, errorMessage);
00058     buildMessage(vl);
00059     va_end(vl);
00060 }
00061 
00062 void FesaException::buildMessage(va_list vl)
00063 {
00064     preloadMessages();
00065 
00066     // if the error code is not there then the message is the error code
00067     if (messages_.find(errorCode_) == messages_.end())
00068     {
00069         std::stringstream result;
00070 
00071         result << "Exception: " << errorCode_ << ". " << file_ << ":" << lineNumber_;
00072         message_ = result.str();
00073     }
00074     else
00075     {
00076         message_ = messages_[errorCode_];
00077         char* parameter = NULL;
00078         uint32_t i = 0;
00079 
00080         // replace the appearances of the strings $1,$2 ... by the parameters
00081         while (true)
00082         {
00083             ++i;
00084             char buf[8];
00085             int32_t nb = snprintf(buf, 8, "$%d", i);
00086             int32_t pos = static_cast<int32_t>(message_.find(buf, 0));
00087             if (pos == -1)
00088                 break;
00089 
00090             parameter = NULL;
00091             parameter = va_arg(vl,char*);
00092             //if something looks starnge, just break ...we dont want to have a segmentation fault here
00093             if (parameter == NULL || parameter == (void*) -1)
00094                 break;
00095 
00096             message_ = message_.replace(pos, nb, parameter);
00097 
00098         }
00099         std::stringstream result;
00100 
00101         result << "Exception: " << errorCode_ << " " << message_ << ". " << file_ << ":" << lineNumber_;
00102         message_ = result.str();
00103 
00104     }
00105 
00106 }
00107 
00108 FesaException::~FesaException() throw()
00109 {
00110 }
00111 
00112 const char* FesaException::what() const throw()
00113 {
00114     return message_.c_str();
00115 }
00116 
00117 const std::string& FesaException::getMessage() const
00118 {
00119     return message_;
00120 }
00121 
00122 long FesaException::getErrorCodeAsLong()
00123 {
00124     int32_t result;
00125     std::stringstream convert;
00126 
00127     std::string::iterator iter;
00128     for(iter=errorCode_.begin();iter!=errorCode_.end();iter++)
00129     {
00130         if(isdigit(*iter))//all digits found there
00131         {
00132             convert << *iter;
00133         }
00134     }
00135     convert >> result;
00136     return result;
00137 }
00138 
00139 void FesaException::preloadMessages()
00140 {
00141     // Accessing shared data, protection is needed
00142     Lock lock(exceptionMutex);
00143     // Check if the messages have been loaded yet
00144     if (messagesLoaded_)
00145     {
00146         return;
00147     }
00148     const ProcessConfiguration* configuration = AbstractEquipment::getInstance()->getProcessConfiguration();
00149     const std::string msgConfigFileName = configuration->getMsgConfigFile();
00150     const std::string labMsgConfigFileName = configuration->getLabMsgConfigFile();
00151     loadMessagesFile(msgConfigFileName);
00152     {
00153         std::ostringstream infoStringStream;
00154         infoStringStream << "Exception messages loaded from " << msgConfigFileName;
00155         LOG_INFO_IF(logger, infoStringStream.str());
00156     }
00157     loadMessagesFile(labMsgConfigFileName);
00158     {
00159         std::ostringstream infoStringStream;
00160         infoStringStream << "Lab-specific exception messages loaded from " << labMsgConfigFileName;
00161         LOG_INFO_IF(logger, infoStringStream.str());
00162     }
00163     messagesLoaded_ = true;
00164 }
00165 
00166 void FesaException::loadMessagesFile(const std::string& file)
00167 {
00168     try
00169     {
00170         std::ifstream ifs(file.c_str());
00171 
00172         if (ifs.fail())//failed to open?
00173         {
00174             //since we dont know where the exception-message file is, we have to use simple Exceptions here
00175             std::string message;
00176             message += "The Exception-Messagefile: '";
00177             message += file;
00178             message += "' is either empty, corrupt or does not exist !";
00179             throw FesaException(__FILE__, __LINE__,message);
00180         }
00181         else
00182         {
00183             //parameters
00184             std::set<std::string> options;
00185             options.insert("*");
00186 
00187             size_t sep1 = 0;
00188             std::string strLine;
00189             while(!ifs.eof())
00190             {
00191                 getline(ifs,strLine);
00192                 sep1 = strLine.find('=', 0);
00193                 std::string string_key(strLine.substr(0, sep1));
00194                 std::string value(strLine.substr(sep1+1, strLine.length()-sep1));
00195                 FesaException::messages_[string_key] = value;
00196             }
00197         }
00198     }
00199     catch (std::exception e)
00200     {
00201         std::string message = e.what();
00202         throw FesaException(__FILE__, __LINE__,message);
00203     }
00204 
00205 }
00206 
00207 /****************************** EXCEPTION SPECIALIZATION ***********************************/
00208 
00209 FesaBadConfigException::FesaBadConfigException(const std::string& file, int32_t lineNumber, const char* errorMessage,
00210                                                ...)
00211 {
00212     errorCode_ = errorMessage;
00213     file_ = file;
00214     lineNumber_ = lineNumber;
00215     va_list vl;
00216     va_start(vl, errorMessage);
00217     buildMessage(vl);
00218     va_end(vl);
00219 }
00220 
00221 FesaBadConfigException::~FesaBadConfigException() throw ()
00222 {
00223 
00224 }
00225 
00226 FesaIOException::FesaIOException(const std::string& file, int32_t lineNumber, const char* errorMessage, ...)
00227 {
00228     errorCode_ = errorMessage;
00229     file_ = file;
00230     lineNumber_ = lineNumber;
00231     va_list vl;
00232     va_start(vl, errorMessage);
00233     buildMessage(vl);
00234     va_end(vl);
00235 }
00236 
00237 FesaIOException::~FesaIOException() throw ()
00238 {
00239 
00240 }
00241 
00242 FesaBadParameterException::FesaBadParameterException(const std::string& file, int32_t lineNumber,
00243                                                      const char* errorMessage, ...)
00244 {
00245     errorCode_ = errorMessage;
00246     file_ = file;
00247     lineNumber_ = lineNumber;
00248     va_list vl;
00249     va_start(vl, errorMessage);
00250     buildMessage(vl);
00251     va_end(vl);
00252 }
00253 FesaBadParameterException::~FesaBadParameterException() throw ()
00254 {
00255 }
00256 
00257 FesaTypeMismatchException::FesaTypeMismatchException(const std::string& file, int32_t lineNumber,
00258                                                      const char* errorMessage, ...)
00259 {
00260     errorCode_ = errorMessage;
00261     file_ = file;
00262     lineNumber_ = lineNumber;
00263     va_list vl;
00264     va_start(vl, errorMessage);
00265     buildMessage(vl);
00266     va_end(vl);
00267 }
00268 
00269 FesaTypeMismatchException::~FesaTypeMismatchException() throw ()
00270 {
00271 }
00272 
00273 FesaInvalidResourceException::FesaInvalidResourceException(const std::string& file, int32_t lineNumber,
00274                                                            const char* errorMessage, ...)
00275 {
00276     errorCode_ = errorMessage;
00277     file_ = file;
00278     lineNumber_ = lineNumber;
00279     va_list vl;
00280     va_start(vl, errorMessage);
00281     buildMessage(vl);
00282     va_end(vl);
00283 }
00284 
00285 FesaInvalidResourceException::~FesaInvalidResourceException() throw ()
00286 {
00287 }
00288 
00289 FesaFileException::FesaFileException(const std::string& file, int32_t lineNumber, const char* errorMessage, ...)
00290 {
00291     errorCode_ = errorMessage;
00292     file_ = file;
00293     lineNumber_ = lineNumber;
00294     va_list vl;
00295     va_start(vl, errorMessage);
00296     buildMessage(vl);
00297     va_end(vl);
00298 }
00299 
00300 FesaFileException::~FesaFileException() throw ()
00301 {
00302 }
00303 
00304 } // fesa

Generated on 18 Jan 2013 for Fesa by  doxygen 1.6.1