00001
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
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
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
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))
00131 {
00132 convert << *iter;
00133 }
00134 }
00135 convert >> result;
00136 return result;
00137 }
00138
00139 void FesaException::preloadMessages()
00140 {
00141
00142 Lock lock(exceptionMutex);
00143
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())
00173 {
00174
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
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
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 }