00001 #include "otsdaq-core/ConfigurationDataFormats/ViewColumnInfo.h"
00002 #include "otsdaq-core/Macros/CoutMacros.h"
00003 #include "otsdaq-core/Macros/StringMacros.h"
00004 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationView.h"
00005
00006 #include <iostream>
00007 #include <sstream>
00008 #include <stdexcept>
00009
00010 using namespace ots;
00011
00012
00013 const std::string ViewColumnInfo::TYPE_UID = "UID";
00014
00015 const std::string ViewColumnInfo::TYPE_DATA = "Data";
00016 const std::string ViewColumnInfo::TYPE_UNIQUE_DATA = "UniqueData";
00017 const std::string ViewColumnInfo::TYPE_MULTILINE_DATA = "MultilineData";
00018 const std::string ViewColumnInfo::TYPE_FIXED_CHOICE_DATA = "FixedChoiceData";
00019 const std::string ViewColumnInfo::TYPE_BITMAP_DATA = "BitMap";
00020
00021 const std::string ViewColumnInfo::TYPE_ON_OFF = "OnOff";
00022 const std::string ViewColumnInfo::TYPE_TRUE_FALSE = "TrueFalse";
00023 const std::string ViewColumnInfo::TYPE_YES_NO = "YesNo";
00024
00025 const std::string ViewColumnInfo::TYPE_START_CHILD_LINK = "ChildLink";
00026 const std::string ViewColumnInfo::TYPE_START_CHILD_LINK_UID = "ChildLinkUID";
00027 const std::string ViewColumnInfo::TYPE_START_CHILD_LINK_GROUP_ID = "ChildLinkGroupID";
00028 const std::string ViewColumnInfo::TYPE_START_GROUP_ID = "GroupID";
00029 const std::string ViewColumnInfo::TYPE_COMMENT = "Comment";
00030 const std::string ViewColumnInfo::TYPE_AUTHOR = "Author";
00031 const std::string ViewColumnInfo::TYPE_TIMESTAMP = "Timestamp";
00032
00033
00034 const std::string ViewColumnInfo::DATATYPE_NUMBER = "NUMBER";
00035 const std::string ViewColumnInfo::DATATYPE_STRING = "VARCHAR2";
00036 const std::string ViewColumnInfo::DATATYPE_TIME = "TIMESTAMP WITH TIMEZONE";
00037
00038 const std::string ViewColumnInfo::TYPE_VALUE_YES = "Yes";
00039 const std::string ViewColumnInfo::TYPE_VALUE_NO = "No";
00040 const std::string ViewColumnInfo::TYPE_VALUE_TRUE = "True";
00041 const std::string ViewColumnInfo::TYPE_VALUE_FALSE = "False";
00042 const std::string ViewColumnInfo::TYPE_VALUE_ON = "On";
00043 const std::string ViewColumnInfo::TYPE_VALUE_OFF = "Off";
00044
00045 const std::string ViewColumnInfo::DATATYPE_STRING_DEFAULT = "DEFAULT";
00046 const std::string ViewColumnInfo::DATATYPE_COMMENT_DEFAULT = "No Comment";
00047 const std::string ViewColumnInfo::DATATYPE_BOOL_DEFAULT = "0";
00048 const std::string ViewColumnInfo::DATATYPE_NUMBER_DEFAULT = "0";
00049 const std::string ViewColumnInfo::DATATYPE_TIME_DEFAULT = "0";
00050 const std::string ViewColumnInfo::DATATYPE_LINK_DEFAULT = "NO_LINK";
00051
00052 const std::string ViewColumnInfo::COL_NAME_STATUS = "Status";
00053 const std::string ViewColumnInfo::COL_NAME_PRIORITY = "Priority";
00054
00055
00056
00057
00058
00059
00060 ViewColumnInfo::ViewColumnInfo(const std::string &type, const std::string &name,
00061 const std::string &storageName, const std::string &dataType,
00062 const std::string &dataChoicesCSV, std::string *capturedExceptionString)
00063 : type_ (type)
00064 , name_ (name)
00065 , storageName_(storageName)
00066 , dataType_ (dataType)
00067 , bitMapInfoP_(0)
00068 {
00069
00070 if((type_ != TYPE_DATA) && (type_ != TYPE_UNIQUE_DATA) && (type_ != TYPE_UID) &&
00071 (type_ != TYPE_MULTILINE_DATA) && (type_ != TYPE_FIXED_CHOICE_DATA) &&
00072 (type_ != TYPE_BITMAP_DATA) &&
00073 (type_ != TYPE_ON_OFF) && (type_ != TYPE_TRUE_FALSE) && (type_ != TYPE_YES_NO) &&
00074 (type_ != TYPE_COMMENT) && (type_ != TYPE_AUTHOR) && (type_ != TYPE_TIMESTAMP) &&
00075 !isChildLink() &&
00076 !isChildLinkUID() &&
00077 !isChildLinkGroupID() &&
00078 !isGroupID() )
00079 {
00080 __SS__ << "The type for column " << name_ << " is " << type_ <<
00081 ", while the only accepted types are: " <<
00082 TYPE_DATA << " " <<
00083 TYPE_UNIQUE_DATA << " " <<
00084 TYPE_MULTILINE_DATA << " " <<
00085 TYPE_FIXED_CHOICE_DATA << " " <<
00086 TYPE_UID << " " <<
00087 TYPE_ON_OFF << " " <<
00088 TYPE_TRUE_FALSE << " " <<
00089 TYPE_YES_NO << " " <<
00090 TYPE_START_CHILD_LINK << "-* " <<
00091 TYPE_START_CHILD_LINK_UID << "-* " <<
00092 TYPE_START_CHILD_LINK_GROUP_ID << "-* " <<
00093 TYPE_START_GROUP_ID << "-* " << std::endl;
00094 if(capturedExceptionString) *capturedExceptionString = ss.str();
00095 else throw std::runtime_error(ss.str());
00096 }
00097 else if(capturedExceptionString) *capturedExceptionString = "";
00098
00099
00100
00101 for(unsigned int i=0;i<type_.size();++i)
00102 if(!(
00103 (type_[i] >= 'A' && type_[i] <= 'Z') ||
00104 (type_[i] >= 'a' && type_[i] <= 'z') ||
00105 (type_[i] >= '0' && type_[i] <= '9') ||
00106 (type_[i] == '-' || type_[i] <= '_' || type_[i] <= '.')
00107 ))
00108 {
00109 __SS__ << "The data type for column " << name_ << " is '" << type_ <<
00110 "'. Data types must contain only letters, numbers," <<
00111 "dashes, underscores, and periods." << std::endl;
00112 if(capturedExceptionString) *capturedExceptionString += ss.str();
00113 else throw std::runtime_error(ss.str());
00114 }
00115
00116
00117
00118 if((dataType_ != DATATYPE_NUMBER) &&
00119 (dataType_ != DATATYPE_STRING) &&
00120 (dataType_ != DATATYPE_TIME))
00121 {
00122 __SS__ << "The data type for column " << name_ << " is " << dataType_ <<
00123 ", while the only accepted types are: " <<
00124 DATATYPE_NUMBER << " " <<
00125 DATATYPE_STRING << " " <<
00126 DATATYPE_TIME << std::endl;
00127 if(capturedExceptionString) *capturedExceptionString += ss.str();
00128 else throw std::runtime_error(ss.str());
00129 }
00130
00131
00132 if(dataType_.size() == 0)
00133 {
00134 __SS__ << "The data type for column " << name_ << " is '" << dataType_ <<
00135 "'. Data types must contain at least 1 character." << std::endl;
00136 if(capturedExceptionString) *capturedExceptionString += ss.str();
00137 else throw std::runtime_error(ss.str());
00138 }
00139
00140
00141
00142 for(unsigned int i=0;i<dataType_.size();++i)
00143 if(!(
00144 (dataType_[i] >= 'A' && dataType_[i] <= 'Z') ||
00145 (dataType_[i] >= 'a' && dataType_[i] <= 'z') ||
00146 (dataType_[i] >= '0' && dataType_[i] <= '9') ||
00147 (dataType_[i] == '-' || dataType_[i] <= '_')
00148 ))
00149 {
00150 __SS__ << "The data type for column " << name_ << " is '" << dataType_ <<
00151 "'. Data types must contain only letters, numbers," <<
00152 "dashes, and underscores." << std::endl;
00153 if(capturedExceptionString) *capturedExceptionString += ss.str();
00154 else throw std::runtime_error(ss.str());
00155 }
00156
00157 if(name_.size() == 0)
00158 {
00159 __SS__ << "There is a column named " << name_ <<
00160 "'. Column names must contain at least 1 character." << std::endl;
00161 if(capturedExceptionString) *capturedExceptionString += ss.str();
00162 else throw std::runtime_error(ss.str());
00163 }
00164
00165
00166
00167 for(unsigned int i=0;i<name_.size();++i)
00168 if(!(
00169 (name_[i] >= 'A' && name_[i] <= 'Z') ||
00170 (name_[i] >= 'a' && name_[i] <= 'z') ||
00171 (name_[i] >= '0' && name_[i] <= '9') ||
00172 (name_[i] == '-' || name_[i] <= '_')
00173 ))
00174 {
00175 __SS__ << "There is a column named " << name_ <<
00176 "'. Column names must contain only letters, numbers," <<
00177 "dashes, and underscores." << std::endl;
00178 if(capturedExceptionString) *capturedExceptionString += ss.str();
00179 else throw std::runtime_error(ss.str());
00180 }
00181
00182
00183 if(storageName_.size() == 0)
00184 {
00185 __SS__ << "The storage name for column " << name_ << " is '" << storageName_ <<
00186 "'. Storage names must contain at least 1 character." << std::endl;
00187 if(capturedExceptionString) *capturedExceptionString += ss.str();
00188 else throw std::runtime_error(ss.str());
00189 }
00190
00191
00192
00193 for(unsigned int i=0;i<storageName_.size();++i)
00194 if(!(
00195 (storageName_[i] >= 'A' && storageName_[i] <= 'Z') ||
00196 (storageName_[i] >= '0' && storageName_[i] <= '9') ||
00197 (storageName_[i] == '-' || storageName_[i] <= '_')
00198 ))
00199 {
00200 __SS__ << "The storage name for column " << name_ << " is '" << storageName_ <<
00201 "'. Storage names must contain only capital letters, numbers," <<
00202 "dashes, and underscores." << std::endl;
00203 if(capturedExceptionString) *capturedExceptionString += ss.str();
00204 else throw std::runtime_error(ss.str());
00205 }
00206
00207
00208
00209 {
00210 std::istringstream f(dataChoicesCSV);
00211 std::string s;
00212 while (getline(f, s, ',')) dataChoices_.push_back(
00213 StringMacros::decodeURIComponent(s));
00214
00215
00216 }
00217
00218 try
00219 {
00220 extractBitMapInfo();
00221 }
00222 catch(std::runtime_error &e)
00223 {
00224 if(capturedExceptionString) *capturedExceptionString += e.what();
00225 else throw;
00226 }
00227
00228
00229 }
00230
00231
00232 void ViewColumnInfo::extractBitMapInfo()
00233 {
00234
00235 if(type_ == TYPE_BITMAP_DATA)
00236 {
00237 if(bitMapInfoP_) delete bitMapInfoP_;
00238 bitMapInfoP_ = new BitMapInfo();
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 if(dataChoices_.size() < 16)
00265 {
00266 __SS__ << "The Bit-Map data parameters for column " << name_ <<
00267 " should be size 16, but is size " << dataChoices_.size() <<
00268 ". Bit-Map parameters should be rows, cols, cellBitSize, and min, mid, max color." <<
00269 std::endl;
00270 throw std::runtime_error(ss.str());
00271 }
00272
00273 sscanf(dataChoices_[0].c_str(),"%u",&(bitMapInfoP_->numOfRows_));
00274 sscanf(dataChoices_[1].c_str(),"%u",&(bitMapInfoP_->numOfColumns_));
00275 sscanf(dataChoices_[2].c_str(),"%u",&(bitMapInfoP_->cellBitSize_));
00276
00277 sscanf(dataChoices_[3].c_str(),"%lu",&(bitMapInfoP_->minValue_));
00278 sscanf(dataChoices_[4].c_str(),"%lu",&(bitMapInfoP_->maxValue_));
00279 sscanf(dataChoices_[5].c_str(),"%lu",&(bitMapInfoP_->stepValue_));
00280
00281 bitMapInfoP_->aspectRatio_ = dataChoices_[6];
00282 bitMapInfoP_->minColor_ = dataChoices_[7];
00283 bitMapInfoP_->midColor_ = dataChoices_[8];
00284 bitMapInfoP_->maxColor_ = dataChoices_[9];
00285 bitMapInfoP_->absMinColor_ = dataChoices_[10];
00286 bitMapInfoP_->absMaxColor_ = dataChoices_[11];
00287
00288 bitMapInfoP_->rowsAscending_ = dataChoices_[12] == "Yes"?1:0;
00289 bitMapInfoP_->colsAscending_ = dataChoices_[13] == "Yes"?1:0;
00290 bitMapInfoP_->snakeRows_ = dataChoices_[14] == "Yes"?1:0;
00291 bitMapInfoP_->snakeCols_ = dataChoices_[15] == "Yes"?1:0;
00292 }
00293 }
00294
00295
00296
00297 ViewColumnInfo::ViewColumnInfo(void){}
00298
00299
00300 ViewColumnInfo::ViewColumnInfo(const ViewColumnInfo& c)
00301 :type_(c.type_)
00302 ,name_(c.name_)
00303 ,storageName_(c.storageName_)
00304 ,dataType_(c.dataType_)
00305 ,dataChoices_(c.dataChoices_)
00306 ,bitMapInfoP_(0)
00307 {
00308
00309 extractBitMapInfo();
00310 }
00311
00312
00313 ViewColumnInfo& ViewColumnInfo::operator=(const ViewColumnInfo& c)
00314 {
00315 ViewColumnInfo *retColInfo = new ViewColumnInfo();
00316 retColInfo->type_ = c.type_;
00317 retColInfo->name_ = c.name_;
00318 retColInfo->storageName_ = c.storageName_;
00319 retColInfo->dataType_ = c.dataType_;
00320 retColInfo->dataChoices_ = c.dataChoices_;
00321 retColInfo->bitMapInfoP_ = 0;
00322
00323
00324 retColInfo->extractBitMapInfo();
00325
00326 return *retColInfo;
00327 }
00328
00329
00330 ViewColumnInfo::~ViewColumnInfo(void)
00331 {
00332 if(bitMapInfoP_) delete bitMapInfoP_;
00333 }
00334
00335
00336 const std::string& ViewColumnInfo::getType(void) const
00337 {
00338 return type_;
00339 }
00340
00341
00342 const std::string& ViewColumnInfo::getDefaultValue(void) const
00343 {
00344 if(getDataType() == ViewColumnInfo::DATATYPE_STRING)
00345 {
00346 if(getType() == ViewColumnInfo::TYPE_ON_OFF ||
00347 getType() == ViewColumnInfo::TYPE_TRUE_FALSE ||
00348 getType() == ViewColumnInfo::TYPE_YES_NO)
00349 return (ViewColumnInfo::DATATYPE_BOOL_DEFAULT);
00350 else if(isChildLink())
00351 return (ViewColumnInfo::DATATYPE_LINK_DEFAULT);
00352 else if(getType() == ViewColumnInfo::TYPE_COMMENT)
00353 return (ViewColumnInfo::DATATYPE_COMMENT_DEFAULT);
00354 else
00355 return (ViewColumnInfo::DATATYPE_STRING_DEFAULT);
00356 }
00357 else if(getDataType() == ViewColumnInfo::DATATYPE_NUMBER)
00358 return (ViewColumnInfo::DATATYPE_NUMBER_DEFAULT);
00359 else if(getDataType() == ViewColumnInfo::DATATYPE_TIME)
00360 return (ViewColumnInfo::DATATYPE_TIME_DEFAULT);
00361 else
00362 {
00363 __SS__ << "\tUnrecognized View data type: " << getDataType() << std::endl;
00364 __COUT_ERR__ << "\n" << ss.str();
00365 throw std::runtime_error(ss.str());
00366 }
00367 }
00368
00369
00370 std::vector<std::string> ViewColumnInfo::getAllTypesForGUI(void)
00371 {
00372 std::vector<std::string> all;
00373 all.push_back(TYPE_DATA);
00374 all.push_back(TYPE_UNIQUE_DATA);
00375 all.push_back(TYPE_FIXED_CHOICE_DATA);
00376 all.push_back(TYPE_MULTILINE_DATA);
00377 all.push_back(TYPE_BITMAP_DATA);
00378 all.push_back(TYPE_ON_OFF);
00379 all.push_back(TYPE_TRUE_FALSE);
00380 all.push_back(TYPE_YES_NO);
00381 all.push_back(TYPE_START_CHILD_LINK_UID);
00382 all.push_back(TYPE_START_CHILD_LINK_GROUP_ID);
00383 all.push_back(TYPE_START_CHILD_LINK);
00384 all.push_back(TYPE_START_GROUP_ID);
00385 return all;
00386 }
00387
00388
00389 std::vector<std::string> ViewColumnInfo::getAllDataTypesForGUI(void)
00390 {
00391 std::vector<std::string> all;
00392 all.push_back(DATATYPE_STRING);
00393 all.push_back(DATATYPE_NUMBER);
00394 all.push_back(DATATYPE_TIME);
00395 return all;
00396 }
00397
00398
00399
00400 std::map<std::pair<std::string,std::string>,std::string> ViewColumnInfo::getAllDefaultsForGUI(void)
00401 {
00402 std::map<std::pair<std::string,std::string>,std::string> all;
00403 all[std::pair<std::string,std::string>(DATATYPE_NUMBER,"*")] = DATATYPE_NUMBER_DEFAULT;
00404 all[std::pair<std::string,std::string>(DATATYPE_TIME,"*")] = DATATYPE_TIME_DEFAULT;
00405
00406 all[std::pair<std::string,std::string>(DATATYPE_STRING,TYPE_ON_OFF)] = DATATYPE_BOOL_DEFAULT;
00407 all[std::pair<std::string,std::string>(DATATYPE_STRING,TYPE_TRUE_FALSE)] = DATATYPE_BOOL_DEFAULT;
00408 all[std::pair<std::string,std::string>(DATATYPE_STRING,TYPE_YES_NO)] = DATATYPE_BOOL_DEFAULT;
00409
00410 all[std::pair<std::string,std::string>(DATATYPE_STRING,TYPE_START_CHILD_LINK)] = DATATYPE_LINK_DEFAULT;
00411 all[std::pair<std::string,std::string>(DATATYPE_STRING,"*")] = DATATYPE_STRING_DEFAULT;
00412 return all;
00413 }
00414
00415
00416 const std::string& ViewColumnInfo::getName(void) const
00417 {
00418 return name_;
00419 }
00420
00421
00422 const std::string& ViewColumnInfo::getStorageName(void) const
00423 {
00424 return storageName_;
00425 }
00426
00427
00428 const std::string& ViewColumnInfo::getDataType(void) const
00429 {
00430 return dataType_;
00431 }
00432
00433
00434 const std::vector<std::string>& ViewColumnInfo::getDataChoices(void) const
00435 {
00436 return dataChoices_;
00437 }
00438
00439
00440
00441
00442 const ViewColumnInfo::BitMapInfo& ViewColumnInfo::getBitMapInfo(void) const
00443 {
00444 if(bitMapInfoP_) return *bitMapInfoP_;
00445
00446
00447 {
00448 __SS__ << "getBitMapInfo request for non-BitMap column of type: " << getType() << std::endl;
00449 __COUT_ERR__ << "\n" << ss.str();
00450 throw std::runtime_error(ss.str());
00451 }
00452
00453 }
00454
00455
00456
00457
00458
00459 const bool ViewColumnInfo::isChildLink(void) const
00460 {
00461 return (type_.find(TYPE_START_CHILD_LINK) == 0 &&
00462 type_.length() > TYPE_START_CHILD_LINK.length() &&
00463 type_[TYPE_START_CHILD_LINK.length()] == '-');
00464 }
00465
00466
00467
00468
00469
00470 const bool ViewColumnInfo::isChildLinkUID(void) const
00471 {
00472 return (type_.find(TYPE_START_CHILD_LINK_UID) == 0 &&
00473 type_.length() > TYPE_START_CHILD_LINK_UID.length() &&
00474 type_[TYPE_START_CHILD_LINK_UID.length()] == '-');
00475 }
00476
00477
00478
00479
00480
00481 const bool ViewColumnInfo::isChildLinkGroupID(void) const
00482 {
00483 return (type_.find(TYPE_START_CHILD_LINK_GROUP_ID) == 0 &&
00484 type_.length() > TYPE_START_CHILD_LINK_GROUP_ID.length() &&
00485 type_[TYPE_START_CHILD_LINK_GROUP_ID.length()] == '-');
00486 }
00487
00488
00489
00490
00491
00492 const bool ViewColumnInfo::isGroupID(void) const
00493 {
00494 return (type_.find(TYPE_START_GROUP_ID) == 0 &&
00495 type_.length() > TYPE_START_GROUP_ID.length() &&
00496 type_[TYPE_START_GROUP_ID.length()] == '-');
00497 }
00498
00499
00500
00501 std::string ViewColumnInfo::getChildLinkIndex (void) const
00502 {
00503
00504 if(isChildLink())
00505 return type_.substr(TYPE_START_CHILD_LINK.length()+1);
00506 else if(isChildLinkUID())
00507 return type_.substr(TYPE_START_CHILD_LINK_UID.length()+1);
00508 else if(isChildLinkGroupID())
00509 return type_.substr(TYPE_START_CHILD_LINK_GROUP_ID.length()+1);
00510 else if(isGroupID())
00511 return type_.substr(TYPE_START_GROUP_ID.length()+1);
00512 else
00513 {
00514 __SS__ << ("Requesting a Link Index from a column that is not a child link member!") << std::endl;
00515 __COUT_ERR__ << ss.str();
00516 throw std::runtime_error(ss.str());
00517 }
00518 }
00519
00520