1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
3 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/TablePlugins/IterateTable.h"
7 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
9 #include <boost/stacktrace.hpp>
11 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
12 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
13 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
15 #include <xdaq/NamespaceURI.h>
24 #define __MF_SUBJECT__ "CfgGUI"
26 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
27 #define TABLE_INFO_EXT std::string("Info.xml")
43 __SUP_COUT__ <<
"Constructor started." << __E__;
48 mkdir(((std::string)ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str(), 0755);
51 __SUP_COUT__ <<
"Constructor complete." << __E__;
55 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
58 void ConfigurationGUISupervisor::init(
void)
60 __SUP_COUT__ <<
"Initializing..." << __E__;
64 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
69 __SUP_COUT__ <<
"Done with test context." << __E__;
73 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
74 "will not launch when this test fails. "
75 <<
"Check the active context group from within Wizard Mode."
80 refreshUserSession(
"" , 1);
86 void ConfigurationGUISupervisor::destroy(
void)
88 __SUP_COUT__ <<
"Destructing..." << __E__;
91 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
92 userConfigurationManagers_.begin();
93 it != userConfigurationManagers_.end();
99 userConfigurationManagers_.clear();
101 if(ConfigurationInterface::getInstance() !=
nullptr)
102 delete ConfigurationInterface::getInstance();
107 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
109 cgicc::Cgicc cgiIn(in);
110 std::string configWindowName =
112 if(configWindowName ==
"tableEditor")
113 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
114 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
115 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
116 if(configWindowName ==
"iterate")
117 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
118 "src='/WebPath/html/Iterate.html?urn="
119 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
121 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
122 "src='/WebPath/html/ConfigurationGUI.html?urn="
123 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
131 CorePropertySupervisorBase::setSupervisorProperty(
132 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
133 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
134 "deleteTableInfo=255");
136 CorePropertySupervisorBase::setSupervisorProperty(
137 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
141 CorePropertySupervisorBase::setSupervisorProperty(
142 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"get*");
150 CorePropertySupervisorBase::addSupervisorProperty(
151 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
152 "getActiveTableGroups");
155 CorePropertySupervisorBase::setSupervisorProperty(
156 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
161 void ConfigurationGUISupervisor::request(
const std::string& requestType,
164 const WebUsers::RequestUserInfo& userInfo)
169 __COUTTV__(requestType);
238 refreshUserSession(userInfo.username_, (refresh ==
"1"));
243 const std::set<TableGroupKey>& sortedKeys = groupInfo.keys_;
244 __COUTTV__(sortedKeys.size());
247 if(requestType ==
"saveTableInfo")
249 std::string tableName =
251 std::string columnCSV =
253 std::string allowOverwrite =
255 std::string tableDescription =
257 std::string columnChoicesCSV =
260 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
261 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
262 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
263 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
264 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
266 if(!allSupervisorInfo_.isWizardMode())
268 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
269 xmlOut.addTextElementToData(
"Error", ss.str());
272 handleSaveTableInfoXML(xmlOut,
278 allowOverwrite ==
"1");
280 else if(requestType ==
"deleteTableInfo")
282 std::string tableName =
284 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
285 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
287 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
288 requestType ==
"flattenToSystemAliases")
291 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
292 __COUT_WARN__ << requestType <<
" command received! " << __E__;
295 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
297 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
298 std::vector<std::string> hostnames;
301 if(requestType ==
"flattenToSystemAliases" &&
302 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
304 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
305 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
316 auto contexts = contextTable->getContexts();
318 for(
const auto& context : contexts)
325 for(i = 0; i < context.address_.size(); ++i)
326 if(context.address_[i] ==
'/')
328 hostnames.push_back(context.address_.substr(j));
329 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
334 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
341 catch(
const std::exception& e)
343 ss <<
"Exception message: " << e.what();
349 __SUP_COUT_ERR__ <<
"\n" << ss.str();
354 if(hostnames.size() == 0)
356 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
357 "'... Is there a valid Context group activated?"
359 __SUP_COUT_ERR__ <<
"\n" << ss.str();
361 xmlOut.addTextElementToData(
"Error", ss.str());
364 for(
const auto& hostname : hostnames)
366 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
367 "/StartOTS_action_" + hostname +
".cmd");
368 FILE* fp = fopen(fn.c_str(),
"w");
371 if(requestType ==
"gatewayLaunchOTS")
372 fprintf(fp,
"LAUNCH_OTS");
373 else if(requestType ==
"gatewayLaunchWiz")
374 fprintf(fp,
"LAUNCH_WIZ");
375 else if(requestType ==
"flattenToSystemAliases")
377 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
385 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
388 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
391 if(requestType ==
"getVersionTracking")
395 __SUP_COUT__ <<
"type: " << type << __E__;
398 xmlOut.addTextElementToData(
399 "versionTrackingStatus",
400 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
401 else if(type ==
"ON")
403 ConfigurationInterface::setVersionTrackingEnabled(
true);
404 xmlOut.addTextElementToData(
405 "versionTrackingStatus",
406 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
408 else if(type ==
"OFF")
410 ConfigurationInterface::setVersionTrackingEnabled(
false);
411 xmlOut.addTextElementToData(
412 "versionTrackingStatus",
413 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
416 else if(requestType ==
"getColumnTypes")
419 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
420 std::vector<std::string> allDataTypes =
421 TableViewColumnInfo::getAllDataTypesForGUI();
422 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
425 for(
const auto& type : allTypes)
426 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
427 for(
const auto& dataType : allDataTypes)
428 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
430 for(
const auto& colDefault : allDefaults)
432 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
433 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
434 colDefault.first.second);
435 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
439 else if(requestType ==
"getGroupAliases")
444 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
446 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
454 catch(std::runtime_error& e)
456 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
458 __SUP_COUT_ERR__ <<
"\n" << ss.str();
459 xmlOut.addTextElementToData(
"Error", ss.str());
463 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
468 catch(
const std::exception& e)
470 ss <<
"Exception message: " << e.what();
475 __SUP_COUT_ERR__ <<
"\n" << ss.str();
476 xmlOut.addTextElementToData(
"Error", ss.str());
480 handleGroupAliasesXML(xmlOut, cfgMgr);
482 else if(requestType ==
"setGroupAliasInActiveBackbone")
484 std::string groupAliasCSV =
486 std::string groupNameCSV =
488 std::string groupKeyCSV =
491 __SUP_COUTV__(groupAliasCSV);
492 __SUP_COUTV__(groupNameCSV);
493 __SUP_COUTV__(groupKeyCSV);
495 handleSetGroupAliasInBackboneXML(
496 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
498 else if(requestType ==
"setTableAliasInActiveBackbone")
500 std::string tableAlias =
502 std::string tableName =
506 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
507 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
508 __SUP_COUT__ <<
"version: " << version << __E__;
510 handleSetTableAliasInBackboneXML(xmlOut,
517 else if(requestType ==
"setAliasOfGroupMembers")
519 std::string versionAlias =
521 std::string groupName =
525 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
526 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
527 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
529 handleAliasGroupMembersInBackboneXML(xmlOut,
536 else if(requestType ==
"getVersionAliases")
538 handleVersionAliasesXML(xmlOut, cfgMgr);
540 else if(requestType ==
"getTableGroups")
542 bool doNotReturnMembers =
543 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
547 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
548 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
550 else if(requestType ==
"getTableGroupType")
552 std::string tableList =
554 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
556 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
558 else if(requestType ==
"getTables")
560 handleTablesXML(xmlOut, cfgMgr);
562 else if(requestType ==
"getContextMemberNames")
564 std::set<std::string> members = cfgMgr->getContextMemberNames();
566 for(
auto& member : members)
567 xmlOut.addTextElementToData(
"ContextMember", member);
569 else if(requestType ==
"getBackboneMemberNames")
571 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
573 for(
auto& member : members)
574 xmlOut.addTextElementToData(
"BackboneMember", member);
576 else if(requestType ==
"getIterateMemberNames")
578 std::set<std::string> members = cfgMgr->getIterateMemberNames();
580 for(
auto& member : members)
581 xmlOut.addTextElementToData(
"IterateMember", member);
583 else if(requestType ==
"getSpecificTableGroup")
585 std::string groupName =
589 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
590 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
595 else if(requestType ==
"saveNewTableGroup")
597 std::string groupName =
599 bool ignoreWarnings =
600 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
601 bool allowDuplicates =
602 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
603 bool lookForEquivalent =
604 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
605 std::string tableList =
607 std::string comment =
610 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
611 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
612 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
613 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
614 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
615 __SUP_COUT__ <<
"comment: " << comment << __E__;
626 else if(requestType ==
"getSpecificTable")
628 std::string tableName =
631 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
632 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
635 std::string allowIllegalColumns =
637 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
640 __SUP_COUT__ <<
"rawData: " << (rawData ==
"1") << __E__;
642 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
643 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
647 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
649 if(allTableInfo.find(tableName) != allTableInfo.end())
651 if(versionStr ==
"" &&
652 allTableInfo.at(tableName).versions_.size())
655 auto it = allTableInfo.at(tableName).versions_.rbegin();
656 if(it->isScratchVersion())
660 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
663 std::map<std::string ,
667 std::string versionAlias;
668 versionAlias = versionStr.substr(
669 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
680 if(versionAliases.find(tableName) != versionAliases.end() &&
681 versionAliases[tableName].find(versionAlias) !=
682 versionAliases[tableName].end())
684 version = versionAliases[tableName][versionAlias];
685 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
690 << versionStr.substr(
691 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
692 <<
"'was not found in active version aliases!" << __E__;
695 version = atoi(versionStr.c_str());
698 __SUP_COUT__ <<
"version: " << version << __E__;
700 handleGetTableXML(xmlOut,
704 (allowIllegalColumns ==
"1"),
707 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
709 else if(requestType ==
"saveSpecificTable")
711 std::string tableName =
713 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
714 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
715 bool sourceTableAsIs =
716 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
717 bool lookForEquivalent =
718 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
719 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
720 std::string comment =
727 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
728 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
730 __SUP_COUT__ <<
"comment: " << comment << __E__;
731 __SUP_COUT__ <<
"data: " << data << __E__;
732 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
733 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
747 else if(requestType ==
"clearTableTemporaryVersions")
749 std::string tableName =
751 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
757 catch(std::runtime_error& e)
759 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
760 xmlOut.addTextElementToData(
761 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
765 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
766 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
769 else if(requestType ==
"clearTableCachedVersions")
771 std::string tableName =
773 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
784 catch(std::runtime_error& e)
786 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
787 xmlOut.addTextElementToData(
788 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
792 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
793 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
796 else if(requestType ==
"getTreeView")
803 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
804 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
808 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
809 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
810 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
811 __SUP_COUTT__ <<
"depth: " << depth << __E__;
812 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
813 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
814 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
816 handleFillTreeViewXML(xmlOut,
828 else if(requestType ==
"getTreeNodeCommonFields")
836 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
838 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
839 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
840 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
841 __SUP_COUT__ <<
"depth: " << depth << __E__;
844 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
845 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
846 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
848 handleFillTreeNodeCommonFieldsXML(xmlOut,
858 else if(requestType ==
"getUniqueFieldValuesForRecords")
867 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
868 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
869 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
870 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
871 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
872 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
874 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
883 else if(requestType ==
"getTreeNodeFieldValues")
892 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
893 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
894 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
895 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
896 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
897 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
899 handleFillGetTreeNodeFieldValuesXML(xmlOut,
908 else if(requestType ==
"setTreeNodeFieldValues")
918 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
919 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
920 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
921 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
922 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
923 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
924 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
926 handleFillSetTreeNodeFieldValuesXML(xmlOut,
937 else if(requestType ==
"addTreeNodeRecords")
945 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
946 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
947 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
948 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
949 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
951 handleFillCreateTreeNodeRecordsXML(xmlOut,
960 else if(requestType ==
"deleteTreeNodeRecords")
968 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
969 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
970 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
971 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
972 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
974 handleFillDeleteTreeNodeRecordsXML(xmlOut,
982 else if(requestType ==
"renameTreeNodeRecords")
991 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
992 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
993 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
994 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
995 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
996 __SUP_COUTV__(newRecordList);
998 handleFillRenameTreeNodeRecordsXML(xmlOut,
1007 else if(requestType ==
"copyTreeNodeRecords")
1014 unsigned int numberOfCopies =
1015 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1019 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1020 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1021 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1022 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1023 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1024 __SUP_COUTV__(numberOfCopies);
1026 handleFillCopyTreeNodeRecordsXML(xmlOut,
1035 else if(requestType ==
"getTableStructureStatusAsJSON")
1042 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1043 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1044 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1045 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1048 setupActiveTablesXML(xmlOut,
1057 xmlOut.addTextElementToData(
1058 "StructureStatusAsJSON",
1059 cfgMgr->
getTableByName(tableName)->getStructureStatusAsJSON(cfgMgr));
1061 catch(
const std::runtime_error& e)
1063 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1064 "seem to be supported for the table '"
1066 <<
".' Make sure you have the expected table plugin in your path, "
1067 "or contact system admins."
1069 ss <<
"Here is the error: " << e.what() << __E__;
1073 else if(requestType ==
"getArtdaqNodes")
1077 __SUP_COUTV__(modifiedTables);
1079 handleGetArtdaqNodeRecordsXML(xmlOut, cfgMgr, modifiedTables);
1081 else if(requestType ==
"saveArtdaqNodes")
1085 std::string subsystemString =
1088 __SUP_COUTV__(modifiedTables);
1089 __SUP_COUTV__(nodeString);
1090 __SUP_COUTV__(subsystemString);
1092 handleSaveArtdaqNodeRecordsXML(
1093 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1095 else if(requestType ==
"getArtdaqNodeLayout")
1097 std::string contextGroupName =
1101 __SUP_COUTV__(contextGroupName);
1102 __SUP_COUTV__(contextGroupKey);
1104 handleLoadArtdaqNodeLayoutXML(
1105 xmlOut, cfgMgr, contextGroupName,
TableGroupKey(contextGroupKey));
1107 else if(requestType ==
"saveArtdaqNodeLayout")
1110 std::string contextGroupName =
1114 __SUP_COUTV__(layout);
1115 __SUP_COUTV__(contextGroupName);
1116 __SUP_COUTV__(contextGroupKey);
1118 handleSaveArtdaqNodeLayoutXML(
1119 xmlOut, cfgMgr, layout, contextGroupName,
TableGroupKey(contextGroupKey));
1121 else if(requestType ==
"checkAffectedActiveGroups")
1126 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1127 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1128 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1130 handleGetAffectedGroupsXML(
1131 xmlOut, cfgMgr, groupName,
TableGroupKey(groupKey), modifiedTables);
1133 else if(requestType ==
"saveTreeNodeEdit")
1137 std::string targetTableVersion =
1143 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1144 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1145 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1146 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1147 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1148 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1150 handleSaveTreeNodeEditXML(xmlOut,
1158 userInfo.username_);
1160 else if(requestType ==
"getLinkToChoices")
1163 std::string linkToTableVersion =
1170 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1171 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1172 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1173 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1174 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1176 handleGetLinkToChoicesXML(xmlOut,
1184 else if(requestType ==
"activateTableGroup")
1188 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1190 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1192 __SUP_COUTV__(ignoreWarnings);
1195 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1196 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1197 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1201 std::string accumulatedErrors, groupTypeString;
1207 groupName,
TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1209 if(accumulatedErrors !=
"")
1213 __SS__ <<
"Throwing exception on accumulated errors: "
1214 << accumulatedErrors << __E__;
1218 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1219 << accumulatedErrors << __E__;
1220 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1222 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1224 catch(std::runtime_error& e)
1229 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1230 xmlOut.addTextElementToData(
1232 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1233 ".' Please see details below:\n\n" + std::string(e.what()));
1234 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1235 <<
" (" << groupKey <<
")" << __E__;
1244 catch(cet::exception& e)
1250 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1251 xmlOut.addTextElementToData(
"Error",
1252 "Error activating table group '" + groupName +
1253 "(" + groupKey +
")" +
"!'\n\n" +
1254 std::string(e.what()));
1255 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1256 <<
" (" << groupKey <<
")" << __E__;
1267 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1279 else if(requestType ==
"getActiveTableGroups")
1281 else if(requestType ==
"copyViewToCurrentColumns")
1283 std::string tableName =
1287 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1288 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1289 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1295 newTemporaryVersion =
1298 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1300 catch(std::runtime_error& e)
1302 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1303 xmlOut.addTextElementToData(
"Error",
1304 "Error copying view from '" + tableName +
"_v" +
1305 sourceVersion +
"'! " +
1306 std::string(e.what()));
1310 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1311 xmlOut.addTextElementToData(
1313 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1316 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1318 else if(requestType ==
"getLastTableGroups")
1321 std::map<std::string ,
1322 std::tuple<std::string ,
1327 theRemoteWebUsers_.getLastTableGroups(theGroups);
1329 for(
const auto& theGroup : theGroups)
1331 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1332 std::get<0>(theGroup.second));
1333 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1334 std::get<1>(theGroup.second).toString());
1335 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1336 std::get<2>(theGroup.second));
1369 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1371 else if(requestType ==
"getSubsytemTableGroups")
1373 std::string subsystem =
1375 __SUP_COUTV__(subsystem);
1376 handleOtherSubsystemActiveGroups(
1377 xmlOut, cfgMgr,
true , subsystem);
1379 else if(requestType ==
"diffWithActiveGroup")
1381 std::string groupName =
1384 __SUP_COUTV__(groupName);
1385 __SUP_COUTV__(groupKey);
1390 else if(requestType ==
"diffWithGroupKey")
1392 std::string groupName =
1396 std::string diffGroupName =
1398 __SUP_COUTV__(groupName);
1399 __SUP_COUTV__(groupKey);
1400 __SUP_COUTV__(diffKey);
1401 __SUP_COUTV__(diffGroupName);
1403 handleGroupDiff(xmlOut,
1410 else if(requestType ==
"diffTableVersions")
1412 std::string tableName =
1416 __SUP_COUTV__(tableName);
1421 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1424 if(allTableInfo.find(tableName) != allTableInfo.end())
1426 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1429 std::map<std::string ,
1433 std::string versionAlias;
1435 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1437 if(versionAliases.find(tableName) != versionAliases.end() &&
1438 versionAliases[tableName].find(versionAlias) !=
1439 versionAliases[tableName].end())
1441 versionA = versionAliases[tableName][versionAlias];
1442 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1445 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1446 <<
"'was not found in active version aliases!"
1450 versionA = atoi(vA.c_str());
1452 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1455 std::map<std::string ,
1459 std::string versionAlias;
1461 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1463 if(versionAliases.find(tableName) != versionAliases.end() &&
1464 versionAliases[tableName].find(versionAlias) !=
1465 versionAliases[tableName].end())
1467 versionB = versionAliases[tableName][versionAlias];
1468 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1471 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1472 <<
"'was not found in active version aliases!"
1476 versionB = atoi(vB.c_str());
1480 versionA = atoi(vA.c_str());
1481 versionB = atoi(vB.c_str());
1484 __SUP_COUTV__(versionA);
1485 __SUP_COUTV__(versionB);
1487 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1489 else if(requestType ==
"savePlanCommandSequence")
1492 std::string commands =
1498 __SUP_COUTV__(modifiedTables);
1499 __SUP_COUTV__(planName);
1500 __SUP_COUTV__(commands);
1501 __SUP_COUTV__(groupName);
1502 __SUP_COUTV__(groupKey);
1504 handleSavePlanCommandSequenceXML(xmlOut,
1513 else if(requestType ==
"mergeGroups")
1515 std::string groupANameContext =
1517 std::string groupAKeyContext =
1519 std::string groupBNameContext =
1521 std::string groupBKeyContext =
1523 std::string groupANameConfig =
1526 std::string groupBNameConfig =
1531 __SUP_COUTV__(groupANameContext);
1532 __SUP_COUTV__(groupAKeyContext);
1533 __SUP_COUTV__(groupBNameContext);
1534 __SUP_COUTV__(groupBKeyContext);
1535 __SUP_COUTV__(groupANameConfig);
1536 __SUP_COUTV__(groupAKeyConfig);
1537 __SUP_COUTV__(groupBNameConfig);
1538 __SUP_COUTV__(groupBKeyConfig);
1539 __SUP_COUTV__(mergeApproach);
1541 handleMergeGroupsXML(xmlOut,
1556 __SUP_SS__ <<
"requestType '" << requestType <<
"' request not recognized."
1558 __SUP_COUT__ <<
"\n" << ss.str();
1559 xmlOut.addTextElementToData(
"Error", ss.str());
1562 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1565 xmlOut, cfgMgr, userInfo.username_);
1566 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1569 catch(
const std::runtime_error& e)
1571 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1572 <<
".' Error: " << e.what() << __E__;
1573 __COUT_ERR__ <<
"\n" << ss.str();
1574 xmlOut.addTextElementToData(
"Error", ss.str());
1579 xmlOut.addTextElementToData(
1581 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1585 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1590 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1591 << requestType <<
".'" << __E__;
1596 catch(
const std::exception& e)
1598 ss <<
"Exception message: " << e.what();
1603 __COUT_ERR__ <<
"\n" << ss.str();
1604 xmlOut.addTextElementToData(
"Error", ss.str());
1609 xmlOut.addTextElementToData(
1611 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1615 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1635 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1638 const std::string& rootGroupName,
1640 const std::string& modifiedTables)
1643 __SUP_COUT__ <<
"rootGroupName " << rootGroupName <<
"(" << rootGroupKey
1644 <<
"). modifiedTables = " << modifiedTables << __E__;
1646 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1651 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
1653 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1654 if(cfgMgr->getFailedTableGroups().find(
1655 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
1656 cfgMgr->getFailedTableGroups().end())
1658 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1659 cfgMgr->getFailedTableGroups().at(
1660 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
1662 else if(cfgMgr->getFailedTableGroups().find(
1663 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1664 cfgMgr->getFailedTableGroups().end())
1666 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1667 cfgMgr->getFailedTableGroups().at(
1668 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1671 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
1672 .second.isInvalid())
1674 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1675 if(cfgMgr->getFailedTableGroups().find(
1676 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
1677 cfgMgr->getFailedTableGroups().end())
1679 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1680 cfgMgr->getFailedTableGroups().at(
1681 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
1683 else if(cfgMgr->getFailedTableGroups().find(
1684 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1685 cfgMgr->getFailedTableGroups().end())
1687 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1688 cfgMgr->getFailedTableGroups().at(
1689 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1698 std::map<std::string ,
TableVersion > rootGroupMemberMap;
1703 &rootGroupMemberMap,
1713 consideredGroups[groupType] =
1714 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1716 catch(
const std::runtime_error& e)
1719 if(rootGroupName.size())
1721 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1722 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1723 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1728 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1729 "name - assuming this was intentional."
1735 if(rootGroupName.size())
1737 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1738 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1743 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1744 "name - assuming this was intentional."
1748 std::map<std::string ,
1751 std::map<std::string ,
1753 modifiedTablesMapIt;
1755 std::istringstream f(modifiedTables);
1756 std::string table, version;
1757 while(getline(f, table,
','))
1759 getline(f, version,
',');
1760 modifiedTablesMap.insert(
1763 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
1767 __SUP_COUT__ << modifiedTables << __E__;
1768 for(
auto& pair : modifiedTablesMap)
1769 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
1774 xercesc::DOMElement* parentEl =
nullptr;
1775 std::string groupComment;
1776 std::vector<std::string> orderedGroupTypes(
1777 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
1778 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
1779 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
1780 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
1781 for(
auto groupType : orderedGroupTypes)
1783 if(consideredGroups.find(groupType) == consideredGroups.end())
1786 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
1788 if(group.second.isInvalid())
1791 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
1792 << group.second <<
")" << __E__;
1810 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1812 for(
auto& table : memberMap)
1814 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1817 table.second != (*modifiedTablesMapIt).second.second)
1819 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1820 << (*modifiedTablesMapIt).second.second << __E__;
1822 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
1823 (*modifiedTablesMapIt).second.first =
true;
1827 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1831 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
1833 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
1835 for(
auto& table : modifiedTablesMap)
1837 if(table.second.first)
1840 if(table.second.second.isMockupVersion() &&
1841 memberMap.find(table.first) == memberMap.end())
1843 __SUP_COUT__ <<
"Found mockup table '" << table.first
1844 <<
"' for Configuration Group." << __E__;
1845 memberMap[table.first] = table.second.second;
1848 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1852 "AddMemberVersion", table.second.second.toString(), parentEl);
1859 __SUP_COUTV__(affected);
1863 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1868 for(
auto& table : memberMap)
1872 "MemberVersion", table.second.toString(), parentEl);
1877 catch(std::runtime_error& e)
1879 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1880 xmlOut.addTextElementToData(
1881 "Error",
"Error getting affected groups! " + std::string(e.what()));
1885 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1886 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1897 void ConfigurationGUISupervisor::setupActiveTablesXML(
1900 const std::string& groupName,
1902 const std::string& modifiedTables,
1904 bool doGetGroupInfo,
1905 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1906 bool outputActiveTables,
1907 std::string* accumulatedErrors)
1910 xmlOut.addTextElementToData(
"tableGroup", groupName);
1911 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.
toString());
1913 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
1919 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
1920 std::string accumulatedWarnings =
"";
1922 &accumulatedWarnings,
1929 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1931 std::map<std::string ,
TableVersion > modifiedTablesMap;
1933 modifiedTablesMapIt;
1935 if(usingActiveGroups)
1938 __SUP_COUT__ <<
"Using active groups." << __E__;
1942 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
1945 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
1954 doGetGroupInfo ? &groupComment : 0,
1955 doGetGroupInfo ? &groupAuthor : 0,
1956 doGetGroupInfo ? &tableGroupCreationTime : 0,
1958 doGetGroupInfo ? &groupType : 0);
1962 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
1963 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
1964 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
1965 xmlOut.addTextElementToData(
"tableGroupType", groupType);
1968 if(accumulatedErrors && *accumulatedErrors !=
"")
1969 __SUP_COUTV__(*accumulatedErrors);
1974 std::istringstream f(modifiedTables);
1975 std::string table, version;
1976 while(getline(f, table,
','))
1978 getline(f, version,
',');
1979 modifiedTablesMap.insert(
1980 std::pair<std::string /*name*/, TableVersion /*version*/>(
1984 for(
auto& pair : modifiedTablesMap)
1985 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1990 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
1991 xmlOut.addTextElementToData(
"DefaultNoLink",
1992 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
1995 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
1996 for(
const auto& tablePair : allActivePairs)
1997 orderedTableSet.emplace(tablePair.first);
1999 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
2000 for(
auto& orderedTableName : orderedTableSet)
2002 tableInfoIt = allTableInfo.find(orderedTableName);
2003 if(tableInfoIt == allTableInfo.end())
2005 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
2010 if(outputActiveTables)
2011 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
2015 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
2016 modifiedTablesMap.end())
2018 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
2019 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
2023 tableInfoIt->second.tablePtr_->setActiveView(
2024 (*modifiedTablesMapIt).second);
2028 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
2029 <<
" failed. Reverting to v"
2030 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2032 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2033 xmlOut.addTextElementToData(
2035 "Error setting up active tables!\n\n" + std::string(ss.str()));
2039 if(outputActiveTables)
2041 xmlOut.addTextElementToData(
2042 "ActiveTableVersion",
2043 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2044 xmlOut.addTextElementToData(
2045 "ActiveTableComment",
2046 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2047 tableInfoIt->second.tablePtr_->getView().getComment());
2052 catch(std::runtime_error& e)
2054 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2056 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2057 xmlOut.addTextElementToData(
"Error", ss.str());
2062 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2067 catch(
const std::exception& e)
2069 ss <<
"Exception message: " << e.what();
2074 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2075 xmlOut.addTextElementToData(
"Error", ss.str());
2094 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2097 const std::string& groupName,
2099 const std::string& startPath,
2100 const std::string& modifiedTables,
2101 const std::string& recordList,
2102 const std::string& author)
2105 setupActiveTablesXML(xmlOut,
2130 bool firstSave =
true;
2137 std::istringstream f(recordList);
2138 std::string recordUID;
2140 while(getline(f, recordUID,
','))
2144 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2149 .isTemporaryVersion())
2151 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2159 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2163 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2169 backupView.copy(table->getView(), temporaryVersion, author);
2178 unsigned int row = table->getViewP()->addRow(
2185 unsigned int col = table->getViewP()->getColStatus();
2186 table->getViewP()->setURIEncodedValue(
"1", row, col);
2193 table->getViewP()->setURIEncodedValue(
2194 recordUID, row, table->getViewP()->getColUID());
2202 table->getViewP()->init();
2206 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2207 __SUP_COUT__ <<
"Before:" << __E__;
2208 table->getViewP()->
print();
2209 table->getViewP()->copy(backupView, temporaryVersion, author);
2210 __SUP_COUT__ <<
"After:" << __E__;
2211 table->getViewP()->
print();
2217 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2219 catch(std::runtime_error& e)
2221 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2223 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2224 xmlOut.addTextElementToData(
"Error", ss.str());
2228 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2233 catch(
const std::exception& e)
2235 ss <<
"Exception message: " << e.what();
2240 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2241 xmlOut.addTextElementToData(
"Error", ss.str());
2248 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2253 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2254 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2255 for(
auto& activePair : allActivePairs)
2257 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2258 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2259 allTableInfo.at(activePair.first)
2260 .tablePtr_->getView()
2263 xmlOut.addTextElementToData(
2264 "NewActiveTableComment",
2265 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2266 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2269 catch(std::runtime_error& e)
2271 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2272 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2273 xmlOut.addTextElementToData(
"Error", ss.str());
2277 __SUP_SS__ << (
"Error!\n\n") << __E__;
2282 catch(
const std::exception& e)
2284 ss <<
"Exception message: " << e.what();
2289 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2290 xmlOut.addTextElementToData(
"Error", ss.str());
2308 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2311 const std::string& groupName,
2313 const std::string& startPath,
2314 const std::string& modifiedTables,
2315 const std::string& recordList)
2318 setupActiveTablesXML(xmlOut,
2343 bool firstSave =
true;
2347 std::istringstream f(recordList);
2348 std::string recordUID;
2351 while(getline(f, recordUID,
','))
2355 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2360 .isTemporaryVersion())
2362 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2370 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2374 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2385 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2386 table->getViewP()->deleteRow(row);
2391 table->getViewP()->init();
2393 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2395 catch(std::runtime_error& e)
2397 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2398 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2399 xmlOut.addTextElementToData(
"Error", ss.str());
2403 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2408 catch(
const std::exception& e)
2410 ss <<
"Exception message: " << e.what();
2415 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2416 xmlOut.addTextElementToData(
"Error", ss.str());
2436 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2439 const std::string& groupName,
2441 const std::string& startPath,
2442 const std::string& modifiedTables,
2443 const std::string& recordList,
2444 const std::string& newRecordList)
2447 setupActiveTablesXML(xmlOut,
2473 std::vector<std::string> recordArray =
2475 std::vector<std::string> newRecordArray =
2481 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2484 <<
"Invalid record size vs new record name size, they must be the same: "
2485 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2491 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2493 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2501 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2504 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2511 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2513 row = table->getViewP()->findRow(
2514 table->getViewP()->getColUID(),
2517 table->getViewP()->setValueAsString(
2518 newRecordArray[i], row, table->getViewP()->getColUID());
2521 table->getViewP()->init();
2523 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2525 catch(std::runtime_error& e)
2527 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2528 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2529 xmlOut.addTextElementToData(
"Error", ss.str());
2533 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2538 catch(
const std::exception& e)
2540 ss <<
"Exception message: " << e.what();
2545 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2546 xmlOut.addTextElementToData(
"Error", ss.str());
2567 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
2570 const std::string& groupName,
2572 const std::string& startPath,
2573 const std::string& modifiedTables,
2574 const std::string& recordList,
2575 unsigned int numberOfCopies )
2581 setupActiveTablesXML(xmlOut,
2607 std::vector<std::string> recordArray =
2613 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2615 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2623 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2626 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2633 for(
const auto& recordUID : recordArray)
2635 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
2637 for(
unsigned int i = 0; i < numberOfCopies; ++i)
2638 table->getViewP()->copyRows(
2648 table->getViewP()->init();
2650 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2652 catch(std::runtime_error& e)
2654 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
2655 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2656 xmlOut.addTextElementToData(
"Error", ss.str());
2660 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
2665 catch(
const std::exception& e)
2667 ss <<
"Exception message: " << e.what();
2672 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2673 xmlOut.addTextElementToData(
"Error", ss.str());
2694 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2697 const std::string& groupName,
2699 const std::string& startPath,
2700 const std::string& modifiedTables,
2701 const std::string& recordList,
2702 const std::string& fieldList,
2703 const std::string& valueList,
2704 const std::string& author)
2707 setupActiveTablesXML(xmlOut,
2722 std::vector<std::string > fieldPaths;
2725 std::istringstream f(fieldList);
2726 std::string fieldPath;
2727 while(getline(f, fieldPath,
','))
2731 __SUP_COUT__ << fieldList << __E__;
2732 for(
const auto& field : fieldPaths)
2733 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2736 std::vector<std::string > fieldValues;
2739 std::istringstream f(valueList);
2740 std::string fieldValue;
2741 while(getline(f, fieldValue,
','))
2743 fieldValues.push_back(fieldValue);
2748 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2749 fieldValues.push_back(
"");
2751 __SUP_COUT__ << valueList << __E__;
2752 for(
const auto& value : fieldValues)
2753 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2756 if(fieldPaths.size() != fieldValues.size())
2759 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2766 std::istringstream f(recordList);
2767 std::string recordUID;
2770 while(getline(f, recordUID,
','))
2775 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2778 for(i = 0; i < fieldPaths.size(); ++i)
2780 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2781 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2786 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2827 if(!(temporaryVersion = table->getViewP()->getVersion())
2828 .isTemporaryVersion())
2838 __SUP_COUT__ <<
"Created temporary version "
2843 __SUP_COUT__ <<
"Using temporary version " << table->
getTableName()
2844 <<
"-v" << temporaryVersion << __E__;
2848 table->getViewP()->setURIEncodedValue(fieldValues[i],
2859 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2861 catch(std::runtime_error& e)
2863 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2865 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2866 xmlOut.addTextElementToData(
"Error", ss.str());
2870 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2875 catch(
const std::exception& e)
2877 ss <<
"Exception message: " << e.what();
2882 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2883 xmlOut.addTextElementToData(
"Error", ss.str());
2902 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2905 const std::string& groupName,
2907 const std::string& startPath,
2908 const std::string& modifiedTables,
2909 const std::string& recordList,
2910 const std::string& fieldList)
2913 setupActiveTablesXML(
2914 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
2921 std::vector<std::string > fieldPaths;
2924 std::istringstream f(fieldList);
2925 std::string fieldPath;
2926 while(getline(f, fieldPath,
','))
2930 __SUP_COUT__ << fieldList << __E__;
2935 std::istringstream f(recordList);
2936 std::string recordUID;
2937 while(getline(f, recordUID,
','))
2941 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2943 xercesc::DOMElement* parentEl =
2944 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2947 for(
const auto& fieldPath : fieldPaths)
2953 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
2965 catch(std::runtime_error& e)
2967 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
2969 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2970 xmlOut.addTextElementToData(
"Error", ss.str());
2974 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
2979 catch(
const std::exception& e)
2981 ss <<
"Exception message: " << e.what();
2986 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2987 xmlOut.addTextElementToData(
"Error", ss.str());
3010 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
3013 const std::string& groupName,
3015 const std::string& startPath,
3017 const std::string& modifiedTables,
3018 const std::string& recordList,
3019 const std::string& fieldList)
3022 setupActiveTablesXML(
3023 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3027 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
3031 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
3032 __SUP_COUT__ << ss.str();
3041 std::vector<ConfigurationTree::RecordField> retFieldList;
3047 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3053 std::vector<std::string > fieldAcceptList, fieldRejectList;
3058 std::istringstream f(fieldList);
3059 std::string fieldPath, decodedFieldPath;
3060 while(getline(f, fieldPath,
','))
3064 if(decodedFieldPath[0] ==
'!')
3065 fieldRejectList.push_back(decodedFieldPath.substr(1));
3067 fieldAcceptList.push_back(decodedFieldPath);
3069 __SUP_COUT__ << fieldList << __E__;
3070 for(
auto& field : fieldAcceptList)
3071 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3072 for(
auto& field : fieldRejectList)
3073 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3077 std::vector<std::string > records;
3078 if(recordList ==
"*")
3082 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3083 for(
auto& record : records)
3084 __SUP_COUT__ <<
"recordList " << record << __E__;
3086 else if(recordList !=
"")
3090 std::istringstream f(recordList);
3091 std::string recordStr;
3092 while(getline(f, recordStr,
','))
3096 __SUP_COUT__ << recordList << __E__;
3097 for(
auto& record : records)
3098 __SUP_COUT__ <<
"recordList " << record << __E__;
3104 records, fieldAcceptList, fieldRejectList, depth);
3108 xercesc::DOMElement* parentTypeEl;
3109 for(
const auto& fieldInfo : retFieldList)
3112 "FieldTableName", fieldInfo.tableName_, parentEl);
3114 "FieldColumnName", fieldInfo.columnName_, parentEl);
3116 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3118 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3120 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3122 fieldInfo.columnInfo_->getDefaultValue(),
3129 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3131 "FieldColumnDataChoice",
3132 fieldInfo.columnInfo_->getDefaultValue(),
3134 for(
const auto& dataChoice : dataChoices)
3136 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3139 catch(std::runtime_error& e)
3141 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3143 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3144 xmlOut.addTextElementToData(
"Error", ss.str());
3148 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3153 catch(
const std::exception& e)
3155 ss <<
"Exception message: " << e.what();
3160 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3161 xmlOut.addTextElementToData(
"Error", ss.str());
3193 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3196 const std::string& groupName,
3198 const std::string& startPath,
3199 const std::string& modifiedTables,
3200 const std::string& recordList,
3201 const std::string& fieldList)
3204 setupActiveTablesXML(
3205 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3211 if(startPath ==
"/")
3217 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3218 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3223 std::vector<std::string > records;
3224 if(recordList ==
"*")
3228 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3229 for(
auto& record : records)
3230 __SUP_COUT__ <<
"recordList " << record << __E__;
3232 else if(recordList !=
"")
3236 std::istringstream f(recordList);
3237 std::string recordStr;
3238 while(getline(f, recordStr,
','))
3242 __SUP_COUT__ << recordList << __E__;
3243 for(
auto& record : records)
3244 __SUP_COUT__ <<
"recordList " << record << __E__;
3249 std::vector<std::string > fieldsToGet;
3254 if(fieldList ==
"AUTO")
3259 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3261 std::vector<ConfigurationTree::RecordField> retFieldList;
3262 std::vector<std::string > fieldAcceptList,
3264 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3266 records, fieldAcceptList, fieldRejectList, 5,
true );
3268 for(
const auto& retField : retFieldList)
3269 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3273 std::istringstream f(fieldList);
3274 std::string fieldPath;
3275 while(getline(f, fieldPath,
','))
3279 __SUP_COUTV__(fieldList);
3288 std::string fieldGroupIDChildLinkIndex;
3289 for(
auto& field : fieldsToGet)
3291 __SUP_COUTV__(field);
3293 xercesc::DOMElement* parentEl =
3294 xmlOut.addTextElementToData(
"field", field);
3300 std::set<std::string > uniqueValues =
3302 records, field, &fieldGroupIDChildLinkIndex);
3304 if(fieldGroupIDChildLinkIndex !=
"")
3306 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3308 for(
auto& uniqueValue : uniqueValues)
3310 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3317 catch(std::runtime_error& e)
3319 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3321 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3322 xmlOut.addTextElementToData(
"Error", ss.str());
3326 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3331 catch(
const std::exception& e)
3333 ss <<
"Exception message: " << e.what();
3338 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3339 xmlOut.addTextElementToData(
"Error", ss.str());
3363 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3366 const std::string& groupName,
3368 const std::string& startPath,
3370 bool hideStatusFalse,
3371 const std::string& modifiedTables,
3372 const std::string& filterList,
3373 const std::string& diffGroupName ,
3376 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3408 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.
isInvalid());
3413 std::string diffAccumulateErrors;
3421 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3438 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3441 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3443 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3444 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3448 for(
auto& memberPair : diffMemberMap)
3450 ->setActiveView(memberPair.second);
3452 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3453 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3454 << lastGroupLoaded.second.first.first <<
"("
3455 << lastGroupLoaded.second.first.second <<
")";
3457 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3458 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3459 << lastGroupLoaded.second.first.first <<
"("
3460 << lastGroupLoaded.second.first.second <<
")";
3463 if(diffCfgMgr->getLastTableGroups().size() == 1)
3465 __SUP_COUT__ <<
"Type already loaded to diff = "
3466 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3469 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3470 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3471 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3472 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3473 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3474 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3475 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3478 <<
"Loading " << groupTypeToLoad
3479 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3480 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3485 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3486 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3487 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3490 for(
auto& memberPair :
3491 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3493 ->setActiveView(memberPair.second);
3501 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3504 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3505 << activeTable.second << __E__;
3507 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3512 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
3515 std::string accumulatedErrors =
"";
3516 setupActiveTablesXML(
3529 if(memberMap.size() >
3531 && startPath ==
"/")
3533 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3536 std::set<std::string > linkingTables;
3541 __COUTS__(30) <<
"Table " << tableInfo.first << __E__;
3542 if(!tableInfo.second.tablePtr_->isActive())
3545 __COUTS__(30) <<
"Table active " << tableInfo.first << __E__;
3547 const TableView& view = tableInfo.second.tablePtr_->getView();
3549 bool addedThisTable =
false;
3550 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
3552 if(!view.getColumnInfo(col).isChildLink())
3555 __COUTS__(30) <<
"Table " << tableInfo.first
3556 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
3558 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
3560 if(view.getDataView()[r][col] ==
"" ||
3561 view.getDataView()[r][col] ==
3562 TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
3567 linkingTables.emplace(tableInfo.first);
3568 addedThisTable =
true;
3570 linkingTables.emplace(
3571 view.getDataView()[r][col]);
3577 std::string missingTables =
"";
3578 for(
const auto& member : memberMap)
3581 if(linkingTables.find(member.first) != linkingTables.end())
3584 if(missingTables.size())
3585 missingTables +=
", ";
3586 missingTables += member.first;
3589 if(missingTables.size())
3591 __COUTV__(missingTables);
3592 std::stringstream ss;
3593 ss <<
"The following member tables of table group '" << groupName <<
"("
3595 <<
")' were identified as possibly orphaned (i.e. no active tables link "
3596 "to these tables, and these tables have no links to other tables):\n\n"
3597 << missingTables <<
".\n"
3599 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
3603 if(accumulatedErrors !=
"")
3605 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
3607 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
3610 __SUP_COUT__ <<
"Active table versions: "
3615 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
3616 __SUP_COUTT__ <<
"Active table versions: "
3622 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
3627 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
3628 std::map<std::string, ConfigurationTree> diffRootMap;
3630 if(startPath ==
"/")
3634 std::string accumulateTreeErrs;
3636 if(usingActiveGroups)
3637 rootMap = cfgMgr->
getChildren(0, &accumulateTreeErrs);
3639 rootMap = cfgMgr->
getChildren(&memberMap, &accumulateTreeErrs);
3644 diffCfgMgr->
getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
3645 __SUP_COUTV__(diffRootMap.size());
3646 for(
auto& diffChild : diffRootMap)
3647 __SUP_COUTV__(diffChild.first);
3650 __SUP_COUTV__(accumulateTreeErrs);
3652 if(accumulateTreeErrs !=
"")
3653 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
3658 cfgMgr->
getNode(startPath,
true );
3661 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
3666 std::map<std::string , std::string > filterMap;
3670 std::set<char>({
';'}) ,
3671 std::set<char>({
'='}) );
3685 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
3690 catch(
const std::runtime_error& e)
3693 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
3700 for(
auto& treePair : rootMap)
3702 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
3706 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
3709 std::set<std::string > rootMapToSearch;
3710 for(
const auto& rootMember : rootMap)
3711 rootMapToSearch.emplace(rootMember.first);
3713 std::stringstream rootSs;
3714 for(
const auto& rootMember : rootMap)
3715 rootSs <<
", " << rootMember.first;
3718 std::stringstream diffRootSs;
3719 for(
const auto& diffMember : diffRootMap)
3721 diffRootSs <<
", " << diffMember.first <<
":"
3722 << diffMember.second.getNodeType();
3723 if(rootMapToSearch.find(diffMember.first) ==
3727 std::stringstream missingSs;
3728 missingSs << diffMember.first <<
3730 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
3733 "diffNodeMissing", missingSs.str(), parentEl);
3736 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
3747 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3748 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3750 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
3751 << diffMember.second.getValueAsString() << __E__;
3753 __SUP_COUTT__ << diffMember.second.nodeDump();
3757 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3758 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3761 for(
auto& treePair : rootMap)
3763 if(diffRootMap.find(treePair.first) == diffRootMap.end())
3765 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3778 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3780 recursiveTreeToXML(treePair.second,
3785 diffRootMap.at(treePair.first));
3790 catch(std::runtime_error& e)
3792 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
3793 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3794 xmlOut.addTextElementToData(
"Error", ss.str());
3798 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
3803 catch(
const std::exception& e)
3805 ss <<
"Exception message: " << e.what();
3810 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3811 xmlOut.addTextElementToData(
"Error", ss.str());
3821 void ConfigurationGUISupervisor::recursiveTreeToXML(
3825 xercesc::DOMElement* parentEl,
3826 bool hideStatusFalse,
3827 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
3837 if(diffTree.has_value() &&
3838 t.
getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
3839 t.
getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
3840 t.
getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
3842 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
3844 if(diffTree->get().isValueNode())
3846 __COUTS__(30) <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
3848 __COUTS__(30) <<
"\t" << diffTree->get().getTableName() <<
"-v"
3849 << diffTree->get().getTableVersion() <<
" ? "
3854 std::stringstream missingSs;
3855 auto diffGroupPair =
3856 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3857 diffTree->get().getTableName());
3858 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
3859 << diffGroupPair.first <<
"(" << diffGroupPair.second
3866 std::stringstream missingSs;
3868 auto diffGroupPair =
3869 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3871 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3872 << diffGroupPair.second <<
") >>>";
3886 if(t.
getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
3887 t.
getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
3892 for(
const auto& choice : choices)
3909 if(diffTree.has_value())
3911 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType()
3918 std::stringstream missingSs;
3920 auto diffGroupPair =
3921 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3923 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3924 << diffGroupPair.second <<
") >>>";
3929 __COUTS__(30) <<
"\t\t diff isDisconnected "
3930 << diffTree->get().isDisconnected() << __E__;
3932 std::stringstream missingSs;
3934 auto diffGroupPair =
3935 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3937 missingSs <<
"<<< Link is "
3938 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
3940 <<
" in " << diffGroupPair.first <<
"("
3941 << diffGroupPair.second <<
") >>>";
3948 std::stringstream missingSs;
3950 auto diffGroupPair =
3951 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3953 missingSs <<
"<<< Link is "
3954 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
3956 <<
" in " << diffGroupPair.first <<
"("
3957 << diffGroupPair.second <<
") >>>";
3962 diffTree->get().getValueAsString())
3965 std::stringstream missingSs;
3967 auto diffGroupPair =
3968 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3970 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
3971 <<
"' in " << diffGroupPair.first <<
"("
3972 << diffGroupPair.second <<
") >>>";
3978 std::stringstream missingSs;
3981 auto dtchildren = diffTree->get().getChildrenMap();
3982 missingSs <<
"<<< Group link";
3983 if(tchildren.size() != dtchildren.size())
3984 missingSs <<
" has " << tchildren.size() <<
" vs "
3985 << dtchildren.size() <<
" children..";
3986 for(
auto& tchild : tchildren)
3987 if(dtchildren.find(tchild.first) == dtchildren.end())
3988 missingSs <<
" '" << tchild.first <<
"' missing..";
3989 for(
auto& dtchild : dtchildren)
3990 if(tchildren.find(dtchild.first) == tchildren.end())
3991 missingSs <<
" '" << dtchild.first <<
"' present...";
3994 if(missingSs.str().length() > std::string(
"<<< Group link").length())
3996 auto diffGroupPair =
3998 .getConfigurationManager()
3999 ->getGroupOfLoadedTable(diffTree->get().getTableName());
4000 missingSs <<
" in " << diffGroupPair.first <<
"("
4001 << diffGroupPair.second <<
") >>>";
4003 "nodeDiff", missingSs.str(), parentEl);
4031 xercesc::DOMElement* choicesParentEl =
4037 __COUTS__(30) <<
"choices.size() " << choices.size() << __E__;
4039 for(
const auto& choice : choices)
4061 xercesc::DOMElement* choicesParentEl =
4065 for(
const auto& choice : choices)
4072 bool returnNode =
true;
4085 if(diffTree.has_value())
4088 <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4097 auto diffGroupPair =
4099 .getConfigurationManager()
4101 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4102 << diffGroupPair.second <<
") >>>";
4104 "nodeDiff", missingSs.str(), parentEl);
4138 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4141 const std::string& linkToTableName,
4143 const std::string& linkIdType,
4144 const std::string& linkIndex,
4145 const std::string& linkInitId)
4158 const std::string& tableName = linkToTableName;
4163 table->setActiveView(version);
4167 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4168 << version << __E__;
4174 __SUP_SS__ <<
"Target table version (" << version
4175 <<
") is not the currently active version (" << table->
getViewVersion()
4176 <<
". Try refreshing the tree." << __E__;
4177 __SUP_COUT_WARN__ << ss.str();
4181 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
4183 if(linkIdType ==
"UID")
4186 unsigned int col = table->getView().getColUID();
4187 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4188 xmlOut.addTextElementToData(
"linkToChoice",
4189 table->getView().getDataView()[row][col]);
4191 else if(linkIdType ==
"GroupID")
4197 __SUP_COUTV__(linkIndex);
4198 __SUP_COUTV__(linkInitId);
4200 std::set<std::string> setOfGroupIDs =
4201 table->getView().getSetOfGroupIDs(linkIndex);
4206 bool foundInitId =
false;
4207 for(
const auto& groupID : setOfGroupIDs)
4209 if(!foundInitId && linkInitId == groupID)
4212 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4216 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4219 unsigned int col = table->getView().getColUID();
4220 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4222 xmlOut.addTextElementToData(
"groupChoice",
4223 table->getView().getDataView()[row][col]);
4224 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4225 xmlOut.addTextElementToData(
"groupMember",
4226 table->getView().getDataView()[row][col]);
4231 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4235 catch(std::runtime_error& e)
4237 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4238 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4239 xmlOut.addTextElementToData(
"Error", ss.str());
4243 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4248 catch(
const std::exception& e)
4250 ss <<
"Exception message: " << e.what();
4255 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4256 xmlOut.addTextElementToData(
"Error", ss.str());
4261 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4264 const std::string& groupANameContext,
4266 const std::string& groupBNameContext,
4268 const std::string& groupANameConfig,
4270 const std::string& groupBNameConfig,
4272 const std::string& author,
4273 const std::string& mergeApproach)
4276 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4277 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4278 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4279 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4280 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4296 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4297 mergeApproach ==
"Skip"))
4299 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4303 std::map<std::string ,
TableVersion > memberMapAContext,
4304 memberMapBContext, memberMapAConfig, memberMapBConfig;
4307 bool skippingContextPair =
false;
4308 bool skippingConfigPair =
false;
4309 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4310 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4312 skippingContextPair =
true;
4313 __SUP_COUTV__(skippingContextPair);
4315 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4316 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4318 skippingConfigPair =
true;
4319 __SUP_COUTV__(skippingConfigPair);
4323 if(!skippingContextPair)
4356 if(!skippingConfigPair)
4393 std::map<std::pair<std::string , std::string >,
4397 std::pair<std::string ,
4398 std::pair<std::string , std::string >>,
4400 groupidConversionMap;
4402 std::stringstream mergeReport;
4403 mergeReport <<
"======================================" << __E__;
4405 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4406 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4407 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4408 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4409 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4410 mergeReport <<
"======================================" << __E__;
4414 for(
unsigned int i = 0; i < 2; ++i)
4416 if(i == 0 && mergeApproach !=
"Rename")
4420 for(
unsigned int j = 0; j < 2; ++j)
4422 if(j == 0 && skippingContextPair)
4424 __COUT__ <<
"Skipping context pair..." << __E__;
4427 else if(j == 1 && skippingConfigPair)
4429 __COUT__ <<
"Skipping table pair..." << __E__;
4434 j == 0 ? memberMapAContext : memberMapAConfig;
4437 j == 0 ? memberMapBContext : memberMapBConfig;
4440 __COUT__ <<
"Context pair..." << __E__;
4442 __COUT__ <<
"Table pair..." << __E__;
4444 __COUT__ <<
"Starting member map B scan." << __E__;
4445 for(
const auto& bkey : memberMapBref)
4447 __SUP_COUTV__(bkey.first);
4449 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4451 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4452 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4453 << bkey.second << __E__;
4456 memberMapAref[bkey.first] = bkey.second;
4458 else if(memberMapAref[bkey.first] != bkey.second)
4461 __SUP_COUTV__(memberMapAref[bkey.first]);
4462 __SUP_COUTV__(bkey.second);
4467 __SUP_COUT__ <<
"Got table." << __E__;
4471 ->getVersionedTableByName(bkey.first,
4472 memberMapAref[bkey.first])
4480 groupidConversionMap,
4484 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME
4490 __SUP_COUTV__(newVersion);
4508 catch(std::runtime_error& e)
4511 <<
"There was an error saving the '"
4513 <<
"' merge result to a persistent table version. "
4514 <<
"Perhaps you can modify this table in one of the "
4515 "groups to resolve this issue, and then re-merge."
4516 << __E__ << e.what();
4520 __SUP_COUTV__(newVersion);
4522 memberMapAref[bkey.first] = newVersion;
4531 if(!skippingContextPair)
4533 __SUP_COUT__ <<
"New context member map complete." << __E__;
4540 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.
toString() +
4541 ") and " + groupBNameContext +
" (" + groupBKeyContext.
toString() +
").");
4544 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
4545 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.
toString());
4547 if(!skippingConfigPair)
4549 __SUP_COUT__ <<
"New table member map complete." << __E__;
4556 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.
toString() +
4557 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.
toString() +
").");
4560 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
4561 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.
toString());
4566 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
4567 std::string mergeReportPath =
"/ServiceData/";
4569 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4570 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
4572 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4575 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
4576 __SUP_COUTV__(mergeReportPath);
4578 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
4581 fprintf(fp,
"%s", mergeReport.str().c_str());
4583 xmlOut.addTextElementToData(
"MergeReportFile",
4584 "/$USER_DATA/" + mergeReportPath);
4587 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
4591 catch(std::runtime_error& e)
4593 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
4594 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4595 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4596 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4597 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
4598 << e.what() << __E__;
4599 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4600 xmlOut.addTextElementToData(
"Error", ss.str());
4604 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
4605 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4606 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4607 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4608 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
4613 catch(
const std::exception& e)
4615 ss <<
"Exception message: " << e.what();
4620 __SUP_COUT_ERR__ <<
"\n" << ss.
str() << __E__;
4621 xmlOut.addTextElementToData(
"Error", ss.str());
4626 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
4629 const std::string& groupName,
4631 const std::string& modifiedTables,
4632 const std::string& author,
4633 const std::string& planName,
4634 const std::string& commandString)
4637 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
4640 setupActiveTablesXML(xmlOut,
4659 for(
const auto& commandPair : IterateTable::commandToTableMap_)
4660 if(commandPair.second !=
"")
4661 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
4678 std::string groupName = planName +
"-Plan";
4679 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
4681 unsigned int groupIdCol =
4682 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
4683 unsigned int cmdTypeCol =
4684 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
4686 unsigned int targetGroupIdCol =
4687 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
4688 unsigned int targetTableCol =
4689 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
4690 unsigned int targetUIDCol =
4691 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
4693 std::string groupLinkIndex =
4694 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
4695 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
4697 std::pair<
unsigned int ,
unsigned int > commandUidLink;
4700 planTable.tableView_->getChildLink(
4701 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
4706 unsigned int cmdRow, cmdCol;
4707 std::string targetGroupName;
4711 std::string targetUID, cmdType;
4713 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
4716 targetUID = planTable.tableView_
4717 ->getDataView()[row][planTable.tableView_->getColUID()];
4718 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4721 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
4723 __SUP_COUT__ <<
"Removing." << __E__;
4727 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
4728 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
4729 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4730 cmdTypeTableIt->second !=
4734 commandTableToEditMap.at(cmdTypeTableIt->second);
4735 cmdRow = cmdTypeTableEdit.tableView_->findRow(
4736 cmdTypeTableEdit.tableView_->getColUID(),
4737 planTable.tableView_
4738 ->getDataView()[row][commandUidLink.second]);
4745 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4746 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4747 targetGroupName = cmdTypeTableEdit.tableView_
4748 ->getDataView()[cmdRow][cmdCol];
4750 for(
unsigned int trow = 0;
4751 trow < targetTable.tableView_->getNumberOfRows();
4755 if(targetTable.tableView_->isEntryInGroup(
4757 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
4758 .getChildLinkIndex(),
4761 __SUP_COUT__ <<
"Removing target." << __E__;
4763 if(targetTable.tableView_->removeRowFromGroup(
4774 __SUP_COUT__ <<
"No targets." << __E__;
4779 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
4785 if(planTable.tableView_->removeRowFromGroup(
4786 row, groupIdCol, groupName,
true ))
4795 std::vector<IterateTable::Command> commands;
4800 std::istringstream f(commandString);
4801 std::string commandSubString, paramSubString, paramValue;
4803 while(getline(f, commandSubString,
';'))
4805 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
4806 std::istringstream g(commandSubString);
4809 while(getline(g, paramSubString,
','))
4811 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
4814 if(paramSubString !=
"type")
4816 __SUP_SS__ <<
"Invalid command sequence" << __E__;
4820 commands.push_back(IterateTable::Command());
4822 getline(g, paramValue,
',');
4824 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4825 commands.back().type_ = paramValue;
4829 getline(g, paramValue,
',');
4831 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4833 commands.back().params_.emplace(
4834 std::pair<std::string ,
4846 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
4853 unsigned int row, tgtRow;
4854 unsigned int targetIndex;
4855 std::string targetStr, cmdUID;
4857 for(
auto& command : commands)
4859 __SUP_COUT__ <<
"command " << command.type_ << __E__;
4860 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
4864 row = planTable.tableView_->addRow(
4865 author,
true ,
"planCommand");
4866 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
4869 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
4872 planTable.tableView_->setValueAsString(
4873 "1", row, planTable.tableView_->getColStatus());
4876 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
4877 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4878 cmdTypeTableIt->second !=
4882 commandTableToEditMap.at(cmdTypeTableIt->second);
4883 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
4888 cmdRow = cmdTypeTableEdit.tableView_->addRow(
4889 author,
true , command.type_ +
"_COMMAND_");
4895 for(
auto& param : command.params_)
4897 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
4900 if(param.first == IterateTable::targetParams_.Tables_)
4902 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
4903 std::istringstream f(param.second);
4906 while(getline(f, targetStr,
'='))
4908 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4909 if(!command.targets_.size() ||
4910 command.targets_.back().table_ !=
"")
4912 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4915 command.addTarget();
4916 command.targets_.back().table_ = targetStr;
4919 command.targets_[targetIndex++].table_ = targetStr;
4925 if(param.first == IterateTable::targetParams_.UIDs_)
4927 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
4928 std::istringstream f(param.second);
4931 while(getline(f, targetStr,
'='))
4933 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4934 if(!command.targets_.size() ||
4935 command.targets_.back().UID_ !=
"")
4937 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4940 command.addTarget();
4941 command.targets_.back().UID_ = targetStr;
4944 command.targets_[targetIndex++].UID_ = targetStr;
4949 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
4951 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
4953 cmdTypeTableEdit.tableView_->setURIEncodedValue(
4954 param.second, cmdRow, cmdCol);
4958 cmdTypeTableEdit.tableView_
4959 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
4961 if(command.targets_.size())
4965 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
4968 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4969 IterateTable::commandTargetCols_.TargetsLink_);
4970 cmdTypeTableEdit.tableView_->setValueAsString(
4971 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
4973 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4974 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4975 cmdTypeTableEdit.tableView_->setValueAsString(
4976 cmdUID +
"_Targets", cmdRow, cmdCol);
4980 for(
const auto& target : command.targets_)
4982 __SUP_COUT__ << target.
table_ <<
" " << target.UID_ << __E__;
4985 tgtRow = targetTable.tableView_->addRow(
4986 author,
true ,
"commandTarget");
4987 targetTable.tableView_->addRowToGroup(
4988 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
4991 targetTable.tableView_->setValueAsString(
4992 target.table_, tgtRow, targetTableCol);
4995 targetTable.tableView_->setValueAsString(
4996 target.UID_, tgtRow, targetUIDCol);
5001 planTable.tableView_->setValueAsString(
5002 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
5003 planTable.tableView_->setValueAsString(
5004 cmdUID, row, commandUidLink.second);
5006 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
5016 planTable.tableView_->print();
5017 planTable.tableView_->init();
5019 __SUP_COUT__ <<
"requestType tables:" << __E__;
5021 for(
auto& modifiedConfig : commandTableToEditMap)
5023 __SUP_COUTV__(modifiedConfig.second.modified_);
5024 modifiedConfig.second.tableView_->print();
5025 modifiedConfig.second.tableView_->init();
5028 targetTable.tableView_->print();
5029 targetTable.tableView_->init();
5034 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5040 if(planTable.createdTemporaryVersion_)
5042 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
5043 << planTable.temporaryVersion_ << __E__;
5046 planTable.temporaryVersion_);
5049 if(targetTable.createdTemporaryVersion_)
5051 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
5052 << targetTable.temporaryVersion_ << __E__;
5055 targetTable.temporaryVersion_);
5058 for(
auto& modifiedConfig : commandTableToEditMap)
5060 if(modifiedConfig.second
5061 .createdTemporaryVersion_)
5063 __SUP_COUT__ <<
"Erasing temporary version "
5064 << modifiedConfig.second.tableName_ <<
"-v"
5065 << modifiedConfig.second.temporaryVersion_ << __E__;
5068 modifiedConfig.second.temporaryVersion_);
5082 planTable.tableName_,
5083 planTable.originalVersion_,
5086 planTable.temporaryVersion_,
5089 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5090 << finalVersion << __E__;
5095 targetTable.tableName_,
5096 targetTable.originalVersion_,
5099 targetTable.temporaryVersion_,
5102 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5103 << finalVersion << __E__;
5105 for(
auto& modifiedConfig : commandTableToEditMap)
5107 if(!modifiedConfig.second.modified_)
5109 if(modifiedConfig.second
5110 .createdTemporaryVersion_)
5112 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5113 << modifiedConfig.second.tableName_ <<
"-v"
5114 << modifiedConfig.second.temporaryVersion_ << __E__;
5117 modifiedConfig.second.temporaryVersion_);
5125 modifiedConfig.second.tableName_,
5126 modifiedConfig.second.originalVersion_,
5128 modifiedConfig.second.table_,
5129 modifiedConfig.second.temporaryVersion_,
5132 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5133 << finalVersion << __E__;
5136 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5138 catch(std::runtime_error& e)
5140 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5141 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5142 xmlOut.addTextElementToData(
"Error", ss.str());
5146 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5151 catch(
const std::exception& e)
5153 ss <<
"Exception message: " << e.what();
5158 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5159 xmlOut.addTextElementToData(
"Error", ss.str());
5172 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(
HttpXmlDocument& xmlOut,
5174 const std::string& tableName,
5176 const std::string& type,
5177 const std::string& uid,
5178 const std::string& colName,
5179 const std::string& newValue,
5180 const std::string& author)
5183 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5184 <<
" type=" << type << __E__;
5194 table->setActiveView(version);
5201 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5202 << version << __E__;
5206 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
5207 __SUP_COUTTV__(table->getView().getComment());
5211 __SUP_SS__ <<
"Target table version (" << version
5212 <<
") is not the currently active version (" << table->
getViewVersion()
5213 <<
"). Try refreshing the tree." << __E__;
5217 unsigned int col = -1;
5218 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5219 col = table->getView().getColUID();
5220 else if(type ==
"node-comment")
5221 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5222 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5223 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5224 col = table->getView().findCol(colName);
5225 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5226 type ==
"table-newUIDRow" || type ==
"table-newRow")
5230 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5235 if(type ==
"table" || type ==
"link-comment")
5238 if(table->getView().isURIEncodedCommentTheSame(newValue))
5241 <<
"' is the same as the current comment. No need to save change."
5259 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5264 __SUP_COUTTV__(table->getView().getComment());
5270 if(type ==
"table" || type ==
"link-comment")
5275 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
5278 unsigned int row = cfgView->
addRow(
5279 author,
true , newValue );
5294 else if(type ==
"table-newGroupRow")
5297 unsigned int csvIndex = newValue.find(
',');
5299 std::string linkIndex = newValue.substr(0, csvIndex);
5300 std::string groupId = newValue.substr(csvIndex + 1);
5303 csvIndex = groupId.find(
',');
5304 std::string newRowUID = groupId.substr(csvIndex + 1);
5305 groupId = groupId.substr(0, csvIndex);
5307 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
5311 unsigned int row = cfgView->
addRow(author,
5337 else if(type ==
"delete-uid")
5340 unsigned int row = cfgView->
findRow(col, uid);
5343 else if(type ==
"tree-copy")
5346 __COUTV__(newValue);
5347 std::vector<std::string> paramArray =
5351 if(paramArray.size() != 2)
5353 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
5354 "copy instances & depth of copy."
5359 unsigned int row = cfgView->
findRow(col, uid);
5362 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
5363 unsigned int depth = atoi(paramArray[1].c_str());
5365 __COUTV__(numberOfInstances);
5366 if(numberOfInstances > 1000)
5368 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
5369 "1000. Number of instances provided was "
5370 << numberOfInstances << __E__;
5377 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
5386 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
5387 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
5393 __SUP_SS__ <<
"Value '" << newValue
5394 <<
"' is the same as the current value. No need to save "
5395 "change to tree node."
5400 else if(type ==
"link-UID" || type ==
"link-GroupID")
5403 std::pair<
unsigned int ,
unsigned int > linkPair;
5407 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
5411 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
5414 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
5416 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
5419 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
5421 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
5422 csvIndexStart = csvIndex + 1;
5423 csvIndex = newValue.find(
',', csvIndexStart);
5424 std::string newLinkId = newValue.substr(
5429 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
5433 bool changed =
false;
5434 bool needSecondaryChange = (type ==
"link-GroupID");
5439 __SUP_COUT__ <<
"Value '" << newTable
5440 <<
"' is the same as the current value." << __E__;
5448 std::string originalValue = cfgView->
getValueAsString(row, linkPair.second);
5452 __SUP_COUT__ <<
"Value '" << newLinkId
5453 <<
"' is the same as the current value." << __E__;
5458 needSecondaryChange =
5464 if(needSecondaryChange)
5466 bool secondaryChanged =
false;
5467 bool defaultIsInGroup =
5473 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
5475 table->eraseView(temporaryVersion);
5496 catch(std::runtime_error&
5499 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
5500 "temporary version."
5502 table->eraseView(temporaryVersion);
5506 xmlOut.addTextElementToData(
5508 "Error saving primary tree node! " + std::string(e.what()));
5518 __SUP_COUTV__(newValue);
5519 csvIndexStart = csvIndex + 1;
5520 csvIndex = newValue.find(
',', csvIndexStart);
5522 csvIndexStart, csvIndex - csvIndexStart));
5525 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5536 table->setActiveView(version);
5543 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
5545 << newTable <<
" v" << version << __E__;
5549 __SUP_COUT__ << newTable <<
" active version is "
5556 ss <<
"Target table '" << newTable
5557 <<
"' is likely not a member of the current table group "
5558 <<
"since the mock-up version was not successfully loaded. "
5563 "To add a table to a group, click the group name to go to "
5565 "group view, then click 'Add/Remove/Modify Member Tables.' "
5567 "can then add or remove tables and save the new group." +
5569 "OR!!! Click the following button to add the table '" +
5571 "' to the currently active Configuration Group: " +
5572 "<input type='button' style='color:black !important;' " +
5573 "title='Click to add table to the active Configuration "
5575 "onclick='addTableToConfigurationGroup(\"" + newTable +
5576 "\"); Debug.closeErrorPop();event.stopPropagation();' "
5577 "value='Add Table'>" +
5581 ss <<
"Target table version (" << version
5582 <<
") is not the currently active version ("
5591 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5597 if(type ==
"link-UID")
5607 __SUP_COUT__ <<
"target col " << col << __E__;
5609 unsigned int row = -1;
5612 row = cfgView->
findRow(col, newLinkId);
5617 if(row == (
unsigned int)-1)
5619 __SUP_COUT__ <<
"New link UID '" << newLinkId
5620 <<
"' was not found, so attempting to change UID of "
5622 << originalValue <<
"'" << __E__;
5625 row = cfgView->
findRow(col, originalValue);
5628 secondaryChanged =
true;
5629 __SUP_COUT__ <<
"Original target record '"
5630 << originalValue <<
"' was changed to '"
5631 << newLinkId <<
"'" << __E__;
5636 __SUP_COUT__ <<
"Original target record '" << originalValue
5637 <<
"' not found." << __E__;
5641 else if(type ==
"link-GroupID")
5649 __SUP_COUT__ <<
"target col " << col << __E__;
5652 std::vector<std::string> memberUIDs;
5655 csvIndexStart = csvIndex + 1;
5656 csvIndex = newValue.find(
',', csvIndexStart);
5657 memberUIDs.push_back(
5658 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
5659 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
5661 (
unsigned int)std::string::npos);
5671 std::string targetUID;
5672 bool shouldBeInGroup;
5675 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
5677 targetUID = cfgView->getDataView()[row][cfgView->
getColUID()];
5678 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5680 shouldBeInGroup =
false;
5681 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
5682 if(targetUID == memberUIDs[i])
5685 shouldBeInGroup =
true;
5692 if(shouldBeInGroup && !isInGroup)
5694 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
5695 secondaryChanged =
true;
5700 else if(!shouldBeInGroup && isInGroup)
5702 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
5703 secondaryChanged =
true;
5707 else if(targetUID ==
5709 ->getDefaultRowValues()[cfgView->
getColUID()] &&
5713 defaultIsInGroup =
true;
5719 if(!secondaryChanged)
5722 <<
"No changes to secondary view. Erasing temporary table."
5724 table->eraseView(temporaryVersion);
5745 catch(std::runtime_error&
5748 __SUP_COUT__ <<
"Caught error while editing secondary table. "
5749 "Erasing temporary version."
5751 table->eraseView(temporaryVersion);
5752 secondaryChanged =
false;
5755 xmlOut.addTextElementToData(
5757 "Error saving secondary tree node! " + std::string(e.what()));
5765 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
5767 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
5769 <<
"', and selected group members are the same as the "
5771 <<
"No need to save changes to tree." << __E__;
5777 else if(0 && !changed)
5782 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
5784 <<
"' are the same as the current values. No need to save "
5785 "change to tree node."
5795 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5796 table->eraseView(temporaryVersion);
5810 catch(std::runtime_error& e)
5812 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
5813 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5814 xmlOut.addTextElementToData(
"Error", ss.str());
5818 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
5823 catch(
const std::exception& e)
5825 ss <<
"Exception message: " << e.what();
5830 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5831 xmlOut.addTextElementToData(
"Error", ss.str());
5875 void ConfigurationGUISupervisor::handleGetTableXML(
HttpXmlDocument& xmlOut,
5877 const std::string& tableName,
5879 bool allowIllegalColumns ,
5883 char tmpIntStr[100];
5884 xercesc::DOMElement *parentEl, *subparentEl;
5886 std::string accumulatedErrors =
"";
5888 if(allowIllegalColumns)
5889 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
5891 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo(
5892 allowIllegalColumns ,
5893 allowIllegalColumns ? &accumulatedErrors : 0,
5902 xmlOut.addTextElementToData(
"ExistingTableNames",
5903 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
5904 for(
auto& configPair : allTableInfo)
5906 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
5907 if(configPair.first == tableName &&
5908 configPair.second.versions_.find(version) ==
5909 configPair.second.versions_.end())
5911 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
5917 xmlOut.addTextElementToData(
"TableName", tableName);
5918 xmlOut.addTextElementToData(
"TableDescription",
5919 table->getTableDescription());
5933 for(
const auto& aliases : versionAliases)
5934 for(
const auto& alias : aliases.second)
5935 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
5936 <<
" ==> " << alias.second << __E__;
5938 catch(
const std::runtime_error& e)
5940 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
5941 << e.what() << __E__;
5944 auto tableIterator = versionAliases.find(tableName);
5946 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
5948 size_t lo = -1, hi = -1;
5949 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
5955 std::vector<std::string> aliases;
5956 if(tableIterator != versionAliases.end())
5959 for(
const auto& aliasPair : tableIterator->second)
5961 if(v == aliasPair.second)
5963 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
5964 << aliasPair.first << __E__;
5965 aliases.push_back(aliasPair.first);
5973 __SUP_COUT__ <<
"Handling version w/aliases" << __E__;
5975 else if(lo ==
size_t(-1))
5977 hi = lo = v.version();
5980 else if(hi + 1 == v.version())
5987 if(lo !=
size_t(-1))
5990 xmlOut.addNumberElementToParent(
"Version", lo, parentEl);
5994 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
5997 hi = lo = v.version();
5999 if(versionAliases.size())
6003 for(
const auto& alias : aliases)
6005 hi = lo = size_t(-1);
6010 if(lo !=
size_t(-1))
6013 xmlOut.addNumberElementToParent(
"Version", lo, parentEl);
6017 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
6028 tableViewPtr = table->getMockupViewP();
6036 std::string localAccumulatedErrors =
"";
6041 allowIllegalColumns ,
6042 &localAccumulatedErrors,
6048 xmlOut.addTextElementToData(
"TableRawData",
6049 tableViewPtr->getSourceRawData());
6051 const std::set<std::string>& srcColNames =
6052 tableViewPtr->getSourceColumnNames();
6053 for(
auto& srcColName : srcColNames)
6054 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
6061 tableViewPtr = cfgMgr
6065 allowIllegalColumns ,
6066 &localAccumulatedErrors,
6072 if(localAccumulatedErrors !=
"")
6073 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6075 catch(std::runtime_error& e)
6077 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6078 <<
"... defaulting to mock-up! " << __E__;
6079 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6081 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6083 tableViewPtr = table->getMockupViewP();
6085 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6089 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6090 <<
"... defaulting to mock-up! "
6091 <<
"(You may want to try again to see what was partially loaded "
6092 "into cache before failure. "
6093 <<
"If you think, the failure is due to a column name change, "
6094 <<
"you can also try to Copy the failing view to the new column "
6096 <<
"'Copy and Move' functionality.)" << __E__;
6101 catch(
const std::exception& e)
6103 ss <<
"Exception message: " << e.what();
6109 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6111 tableViewPtr = table->getMockupViewP();
6113 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6116 xmlOut.addTextElementToData(
"TableVersion", version.
toString());
6122 xercesc::DOMElement* choicesParentEl;
6123 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6125 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6127 for(
int i = 0; i < (int)colInfo.size(); ++i)
6132 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6137 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6141 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6142 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6143 colInfo[i].isChildLink())
6145 for(
auto& choice : colInfo[i].getDataChoices())
6150 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6152 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6159 tableViewPtr->
init();
6161 catch(std::runtime_error& e)
6164 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6171 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6173 for(
int r = 0; r < (int)tableViewPtr->getNumberOfRows(); ++r)
6175 sprintf(tmpIntStr,
"%d", r);
6176 xercesc::DOMElement* tmpParentEl =
6179 for(
int c = 0; c < (int)tableViewPtr->getNumberOfColumns(); ++c)
6181 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6183 std::string timeAsString;
6184 tableViewPtr->
getValue(timeAsString, r, c);
6189 "Entry", tableViewPtr->getDataView()[r][c], tmpParentEl);
6194 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6195 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6196 xmlOut.addTextElementToData(
"TableCreationTime",
6197 std::to_string(tableViewPtr->getCreationTime()));
6198 xmlOut.addTextElementToData(
"TableLastAccessTime",
6199 std::to_string(tableViewPtr->getLastAccessTime()));
6204 std::vector<std::string> defaultRowValues =
6205 table->getMockupViewP()->getDefaultRowValues();
6207 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6209 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6212 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6214 if(accumulatedErrors !=
"")
6216 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6217 "perhaps you can ignore this, ") +
6218 "but please note the following warnings:\n" + accumulatedErrors)
6220 __SUP_COUT_ERR__ << ss.str();
6221 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6225 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6226 tableViewPtr->getSourceColumnMismatch() !=
6229 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6230 <<
":v" << version <<
". Please see the details below:\n\n"
6231 << tableViewPtr->getMismatchColumnInfo();
6233 __SUP_COUT__ <<
"\n" << ss.str();
6234 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6238 catch(std::runtime_error& e)
6240 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6241 __SUP_COUT_ERR__ << ss.str();
6242 xmlOut.addTextElementToData(
"Error", ss.str());
6246 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
6251 catch(
const std::exception& e)
6253 ss <<
"Exception message: " << e.what();
6258 __SUP_COUT_ERR__ << ss.str();
6259 xmlOut.addTextElementToData(
"Error", ss.str());
6270 std::string username,
bool refresh)
6272 uint64_t sessionIndex =
6275 std::stringstream ssMapKey;
6276 ssMapKey << username <<
":" << sessionIndex;
6277 std::string mapKey = ssMapKey.str();
6278 __SUP_COUTT__ <<
"Using Config Session " << mapKey
6279 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
6280 <<
" refresh=" << refresh << __E__;
6282 time_t now = time(0);
6288 for(
auto& pair : userConfigurationManagers_)
6289 __SUP_COUTTV__(pair.first);
6292 const std::string preLoadCfgMgrName =
":0";
6293 if(userConfigurationManagers_.size() == 1 &&
6294 userConfigurationManagers_.find(preLoadCfgMgrName) !=
6295 userConfigurationManagers_.end())
6297 __SUP_COUT__ <<
"Using pre-loaded Configuration Manager. time=" << time(0) <<
" "
6298 << clock() << __E__;
6299 userConfigurationManagers_[mapKey] =
6300 userConfigurationManagers_.at(preLoadCfgMgrName);
6301 userLastUseTime_[mapKey] = userLastUseTime_.at(preLoadCfgMgrName);
6304 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
6306 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
6307 << clock() << __E__;
6313 userConfigurationManagers_[mapKey]->getAllTableInfo(
6321 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
6323 __SUP_SS__ <<
"Fatal error managing userLastUseTime_! Check the logs for "
6324 "Configuration Interface failure."
6326 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6331 (now - userLastUseTime_[mapKey]) >
6332 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
6334 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
6335 userConfigurationManagers_[mapKey]->getAllTableInfo(
6343 __SUP_COUTT__ <<
"Configuration Manager ready. time=" << time(0) <<
" " << clock()
6344 <<
" runTimeSeconds()="
6345 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
6348 userLastUseTime_[mapKey] = now;
6351 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
6352 it != userLastUseTime_.end();
6354 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
6356 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
6358 delete userConfigurationManagers_[it->first];
6359 if(!(userConfigurationManagers_.erase(it->first)))
6361 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
6363 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6366 userLastUseTime_.erase(it);
6373 return userConfigurationManagers_[mapKey];
6381 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(
HttpXmlDocument& xmlOut,
6383 std::string& tableName)
6385 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
6386 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
6387 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
6388 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6392 __SUP_COUT_ERR__ << (
"Error renaming file to " +
6393 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6396 xmlOut.addTextElementToData(
6398 (
"Error renaming Table Info File to " +
6399 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
6414 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
6417 std::string& tableName,
6418 const std::string& data,
6419 const std::string& tableDescription,
6420 const std::string& columnChoicesCSV,
6421 bool allowOverwrite)
6425 std::string capsName;
6430 catch(std::runtime_error& e)
6432 xmlOut.addTextElementToData(
"Error", e.what());
6438 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
6442 xmlOut.addTextElementToData(
"TableName", tableName);
6443 xmlOut.addTextElementToData(
"OverwriteError",
"1");
6444 xmlOut.addTextElementToData(
6446 "File already exists! ('" +
6447 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
6452 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
6453 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
6454 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
6455 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
6458 std::stringstream outss;
6460 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
6461 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
6462 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
6463 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
6464 outss <<
"\t\t\t<VIEW Name=\"" << capsName
6465 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
6471 std::istringstream columnChoicesISS(columnChoicesCSV);
6472 std::string columnChoicesString;
6473 std::string columnDefaultValue, columnMinValue, columnMaxValue;
6474 std::vector<std::string> columnParameters;
6475 std::vector<std::string> columnData =
6478 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
6482 __COUT__ <<
"Column #" << c <<
": "
6484 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
6486 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
6488 __COUT__ <<
"\t creating the new xml" << __E__;
6490 std::string& columnType = columnParameters[0];
6491 std::string& columnName = columnParameters[1];
6492 std::string& columnDataType = columnParameters[2];
6493 const std::string columnStorageName =
6496 outss <<
"\t\t\t\t<COLUMN Type=\"";
6497 outss << columnType;
6498 outss <<
"\" \t Name=\"";
6499 outss << columnName;
6500 outss <<
"\" \t StorageName=\"";
6503 outss << columnStorageName;
6505 catch(std::runtime_error& e)
6507 xmlOut.addTextElementToData(
6509 std::string(
"For column name '") + columnName +
"' - " + e.what());
6512 outss <<
"\" \t DataType=\"";
6513 outss << columnDataType;
6517 std::string* columnDefaultValuePtr =
nullptr;
6518 if(columnDefaultValue !=
6519 TableViewColumnInfo::getDefaultDefaultValue(columnType, columnDataType))
6521 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
6523 outss <<
"\" \t DefaultValue=\"";
6524 outss << columnParameters[3];
6525 columnDefaultValuePtr = &columnParameters[3];
6527 getline(columnChoicesISS, columnChoicesString,
';');
6528 outss <<
"\" \t DataChoices=\"";
6529 outss << columnChoicesString;
6531 std::string* columnMinValuePtr =
nullptr;
6532 std::string* columnMaxValuePtr =
nullptr;
6534 if(columnParameters.size() > 4 &&
6538 if(columnMinValue !=
"")
6540 if(columnMinValue !=
6543 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
6548 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
6549 <<
"' which evaluates to '" << columnMinValue
6550 <<
"' and is not a valid number. The minimum value must "
6551 "be a number (environment variables and math "
6552 "operations are allowed)."
6556 outss <<
"\" \t MinValue=\"" << columnParameters[4];
6557 columnMinValuePtr = &columnParameters[4];
6562 if(columnMaxValue !=
"")
6564 if(columnMaxValue !=
6567 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
6572 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
6573 <<
"' which evaluates to '" << columnMaxValue
6574 <<
"' and is not a valid number. The maximum value must "
6575 "be a number (environment variables and math "
6576 "operations are allowed)."
6580 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
6581 columnMaxValuePtr = &columnParameters[5];
6593 columnDefaultValuePtr,
6594 columnChoicesString,
6600 catch(
const std::runtime_error& e)
6602 __SS__ <<
"Error identified with Column #" << c <<
": \n" << e.what();
6609 outss <<
"\t\t\t</VIEW>\n";
6610 outss <<
"\t\t</TABLE>\n";
6611 outss <<
"\t</ROOT>\n";
6613 __SUP_COUT__ << outss.str() << __E__;
6615 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
6618 xmlOut.addTextElementToData(
"Error",
6619 "Failed to open destination Table Info file:" +
6620 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
6624 fprintf(fp,
"%s", outss.str().c_str());
6627 __SUP_COUT_INFO__ <<
"Finished saving Table Info for '" << tableName
6628 <<
".' Looking for errors in all table column info..." << __E__;
6632 std::string accumulatedErrors =
"";
6636 if(accumulatedErrors !=
"")
6638 __SUP_SS__ << (
"The new version of the '" + tableName +
6639 "' table column info was saved, however errors were detected "
6640 "reading back the table '" +
6641 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
6644 __SUP_COUT_ERR__ << ss.str() << __E__;
6645 xmlOut.addTextElementToData(
"Error", ss.str());
6651 handleGetTableXML(xmlOut, cfgMgr, tableName,
TableVersion());
6654 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
6657 for(
const auto& cfgInfo : allTableInfo)
6663 catch(std::runtime_error& e)
6665 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
6666 <<
"Error identified in column info of table '"
6667 << cfgInfo.first <<
"':\n\n"
6668 << e.what() <<
"\n\n"
6682 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
6685 const std::string& groupAliasCSV,
6686 const std::string& groupNameCSV,
6687 const std::string& groupKeyCSV,
6688 const std::string& author)
6692 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6694 const std::string groupAliasesTableName =
6695 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6696 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6698 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
6700 xmlOut.addTextElementToData(
"Error", ss.str());
6705 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6706 for(
auto& memberName : backboneMembers)
6708 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6709 <<
"\"]=" << activeVersions[memberName] << __E__;
6711 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6712 xmlOut.addTextElementToData(
"oldBackboneVersion",
6713 activeVersions[memberName].toString());
6721 TableVersion originalVersion = activeVersions[groupAliasesTableName];
6724 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6725 bool isDifferent =
false;
6731 unsigned int col = configView->
findCol(
"GroupKeyAlias");
6732 unsigned int ccol = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6733 unsigned int ncol = configView->
findCol(
"GroupName");
6734 unsigned int kcol = configView->
findCol(
"GroupKey");
6737 std::vector<std::string> groupAliases =
6739 std::vector<std::string> groupNames =
6741 std::vector<std::string> groupKeys =
6748 for(
const auto& groupAlias : groupAliases)
6750 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
6753 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
6754 << groupAlias <<
", " << groupNames[i] <<
"("
6755 << groupKeys[i] <<
")}" << __E__;
6760 bool localIsDifferent =
false;
6761 const std::string& groupName = groupNames[i];
6765 unsigned int row = -1;
6769 row = configView->
findRow(col, groupAlias);
6775 if(row == (
unsigned int)-1)
6777 localIsDifferent =
true;
6778 row = configView->
addRow();
6782 "This Group Alias was automatically setup by the server.", row, ccol);
6783 configView->
setValue(groupAlias, row, col);
6786 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6788 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6789 << configView->getDataView()[row][ncol] << __E__;
6790 if(groupName != configView->getDataView()[row][ncol])
6792 configView->
setValue(groupName, row, ncol);
6793 localIsDifferent =
true;
6796 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6797 << configView->getDataView()[row][kcol] << __E__;
6798 if(groupKey.
toString() != configView->getDataView()[row][kcol])
6801 localIsDifferent =
true;
6804 if(localIsDifferent)
6809 configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6813 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
6820 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6823 table->eraseView(temporaryVersion);
6830 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6848 <<
"\t\t**************************** Using the existing table version"
6852 table->eraseView(temporaryVersion);
6853 newAssignedVersion = activeVersions[groupAliasesTableName];
6855 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6856 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
6859 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6861 catch(std::runtime_error& e)
6863 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
6864 __SUP_COUT_ERR__ << ss.str();
6865 xmlOut.addTextElementToData(
"Error", ss.str());
6869 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
6874 catch(
const std::exception& e)
6876 ss <<
"Exception message: " << e.what();
6881 __SUP_COUT_ERR__ << ss.str();
6882 xmlOut.addTextElementToData(
"Error", ss.str());
6893 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
6896 const std::string& tableAlias,
6897 const std::string& tableName,
6899 const std::string& author)
6903 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6905 const std::string versionAliasesTableName =
6906 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6907 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6909 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6911 xmlOut.addTextElementToData(
"Error", ss.str());
6916 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6917 for(
auto& memberName : backboneMembers)
6919 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6920 <<
"\"]=" << activeVersions[memberName] << __E__;
6922 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6923 xmlOut.addTextElementToData(
"oldBackboneVersion",
6924 activeVersions[memberName].toString());
6932 TableVersion originalVersion = activeVersions[versionAliasesTableName];
6935 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6937 bool isDifferent =
false;
6944 unsigned int col2 = configView->
findCol(
"VersionAlias");
6945 unsigned int col3 = configView->
findCol(
"TableName");
6949 unsigned int row = -1;
6954 unsigned int tmpRow = -1;
6957 tmpRow = configView->
findRow(col3, tableName, tmpRow + 1);
6958 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
6965 if(row == (
unsigned int)-1)
6968 row = configView->
addRow();
6971 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6973 std::string(
"Entry was added by server in ") +
6974 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
6978 col = configView->
findCol(
"VersionAliasUID");
6980 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
6982 configView->
setValue(tableAlias, row, col2);
6983 configView->
setValue(tableName, row, col3);
6986 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6988 col = configView->
findCol(
"Version");
6989 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
6990 << configView->getDataView()[row][col] << __E__;
6991 if(version.
toString() != configView->getDataView()[row][col])
7000 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7004 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7009 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
7012 table->eraseView(temporaryVersion);
7019 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7035 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7039 table->eraseView(temporaryVersion);
7040 newAssignedVersion = activeVersions[versionAliasesTableName];
7042 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7043 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7046 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7048 catch(std::runtime_error& e)
7050 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7051 __SUP_COUT_ERR__ << ss.str();
7052 xmlOut.addTextElementToData(
"Error", ss.str());
7056 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7061 catch(
const std::exception& e)
7063 ss <<
"Exception message: " << e.what();
7068 __SUP_COUT_ERR__ << ss.str();
7069 xmlOut.addTextElementToData(
"Error", ss.str());
7078 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
7081 const std::string& versionAlias,
7082 const std::string& groupName,
7084 const std::string& author)
7088 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7090 const std::string versionAliasesTableName =
7091 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7092 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7094 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7096 xmlOut.addTextElementToData(
"Error", ss.str());
7101 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7102 for(
auto& memberName : backboneMembers)
7104 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7105 <<
"\"]=" << activeVersions[memberName] << __E__;
7107 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7108 xmlOut.addTextElementToData(
"oldBackboneVersion",
7109 activeVersions[memberName].toString());
7120 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7125 bool isDifferent =
false;
7144 xmlOut.addTextElementToData(
7147 "\" can not be retrieved!");
7152 unsigned int col2 = configView->
findCol(
"VersionAlias");
7153 unsigned int col3 = configView->
findCol(
"TableName");
7155 for(
auto& memberPair : memberMap)
7157 bool thisMemberIsDifferent =
false;
7158 unsigned int row = -1;
7160 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7161 << memberPair.second <<
" to " << versionAlias << __E__;
7167 unsigned int tmpRow = -1;
7170 tmpRow = configView->
findRow(col3, memberPair.first, tmpRow + 1);
7171 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7178 if(row == (
unsigned int)-1)
7180 thisMemberIsDifferent =
true;
7181 row = configView->
addRow();
7184 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7186 std::string(
"Entry was added by server in ") +
7187 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7193 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
7198 configView->
setValue(versionAlias, row, col2);
7199 configView->
setValue(memberPair.first, row, col3);
7202 col = configView->
findCol(
"Version");
7204 if(memberPair.second.toString() != configView->getDataView()[row][col])
7206 configView->
setValue(memberPair.second.toString(), row, col);
7207 thisMemberIsDifferent =
true;
7210 if(thisMemberIsDifferent)
7213 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7217 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7220 if(thisMemberIsDifferent)
7229 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
7230 <<
" as new table version" << __E__;
7232 newAssignedVersion =
7233 cfgMgr->
saveNewTable(versionAliasesTableName, temporaryVersion);
7237 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7241 table->eraseView(temporaryVersion);
7242 newAssignedVersion = activeVersions[versionAliasesTableName];
7245 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7246 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7247 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
7249 catch(std::runtime_error& e)
7251 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7252 __SUP_COUT_ERR__ << ss.str();
7253 xmlOut.addTextElementToData(
"Error", ss.str());
7257 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7262 catch(
const std::exception& e)
7264 ss <<
"Exception message: " << e.what();
7269 __SUP_COUT_ERR__ << ss.str();
7270 xmlOut.addTextElementToData(
"Error", ss.str());
7284 void ConfigurationGUISupervisor::handleGroupAliasesXML(
HttpXmlDocument& xmlOut,
7288 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7290 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7291 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7293 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
7294 << groupAliasesTableName
7295 <<
" is a required member of the Backbone table group."
7296 <<
"\n\nLikely you need to activate a valid Backbone table group."
7298 __SUP_COUT__ << ss.str();
7303 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
7304 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
7305 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
7306 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
7307 activeVersions[groupAliasesTableName].toString());
7309 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7314 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
7316 if(numOfThreads < 2)
7318 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
7320 for(
auto& aliasNodePair : aliasNodePairs)
7322 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7323 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7325 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7326 xmlOut.addTextElementToData(
"GroupName", groupName);
7327 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7328 xmlOut.addTextElementToData(
7330 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7331 .getValueAsString());
7335 ConfigurationManager::UNKNOWN_INFO;
7336 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7353 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7354 << groupKey <<
")' to extract group comment and type."
7357 xmlOut.addTextElementToData(
"GroupComment", groupComment);
7358 xmlOut.addTextElementToData(
"GroupType", groupType);
7363 int threadsLaunched = 0;
7364 int foundThreadIndex = 0;
7365 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
7366 for(
int i = 0; i < numOfThreads; ++i)
7367 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
7369 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
7370 std::string groupName, groupKey;
7372 for(
auto& aliasNodePair : aliasNodePairs)
7375 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
7377 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7378 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7380 if(threadsLaunched >= numOfThreads)
7383 foundThreadIndex = -1;
7384 while(foundThreadIndex == -1)
7386 for(
int i = 0; i < numOfThreads; ++i)
7387 if(*(threadDone[i]))
7389 foundThreadIndex = i;
7392 if(foundThreadIndex == -1)
7394 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
7398 threadsLaunched = numOfThreads - 1;
7400 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
7401 << groupKey <<
")" << __E__;
7402 *(threadDone[foundThreadIndex]) =
false;
7406 std::string theGroupName,
7408 std::shared_ptr<ots::GroupInfo> theGroupInfo,
7409 std::shared_ptr<std::atomic<bool>> theThreadDone) {
7419 sharedGroupInfoPtrs.back(),
7420 threadDone[foundThreadIndex])
7431 foundThreadIndex = -1;
7432 for(
int i = 0; i < numOfThreads; ++i)
7433 if(!*(threadDone[i]))
7435 foundThreadIndex = i;
7438 if(foundThreadIndex != -1)
7440 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
7444 }
while(foundThreadIndex != -1);
7448 for(
auto& aliasNodePair : aliasNodePairs)
7450 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7451 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7452 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7453 xmlOut.addTextElementToData(
"GroupName", groupName);
7454 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7455 xmlOut.addTextElementToData(
7457 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7458 .getValueAsString());
7460 xmlOut.addTextElementToData(
"GroupComment",
7461 sharedGroupInfoPtrs[i]->latestKeyGroupComment_);
7462 xmlOut.addTextElementToData(
"GroupAuthor",
7463 sharedGroupInfoPtrs[i]->latestKeyGroupAuthor_);
7464 xmlOut.addTextElementToData(
7465 "GroupCreationTime", sharedGroupInfoPtrs[i]->latestKeyGroupCreationTime_);
7466 xmlOut.addTextElementToData(
7467 "GroupType", sharedGroupInfoPtrs[i]->latestKeyGroupTypeString_);
7486 void ConfigurationGUISupervisor::handleVersionAliasesXML(
HttpXmlDocument& xmlOut,
7490 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7492 std::string versionAliasesTableName =
7493 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7494 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7496 __SUP_SS__ <<
"Active version of VersionAliases missing!"
7497 <<
"Make sure you have a valid active Backbone Group." << __E__;
7498 xmlOut.addTextElementToData(
"Error", ss.str());
7501 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
7502 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
7503 xmlOut.addTextElementToData(
"VersionAliasesVersion",
7504 activeVersions[versionAliasesTableName].toString());
7506 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7509 for(
auto& aliasNodePair : aliasNodePairs)
7513 xmlOut.addTextElementToData(
7515 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
7516 xmlOut.addTextElementToData(
7517 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
7518 xmlOut.addTextElementToData(
7519 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
7520 xmlOut.addTextElementToData(
7522 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7523 .getValueAsString());
7533 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
7537 std::string name, versionStr;
7538 auto c = tableList.find(
',', 0);
7541 while(c < tableList.length())
7544 name = tableList.substr(i, c - i);
7546 c = tableList.find(
',', i);
7547 if(c == std::string::npos)
7549 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
7550 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7551 xmlOut.addTextElementToData(
"Error", ss.str());
7555 versionStr = tableList.substr(i, c - i);
7557 c = tableList.find(
',', i);
7562 std::string groupTypeString =
"";
7568 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7570 catch(std::runtime_error& e)
7572 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
7573 __SUP_COUT__ <<
"\n" << ss.str();
7574 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7575 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7579 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
7584 catch(
const std::exception& e)
7586 ss <<
"Exception message: " << e.what();
7591 __SUP_COUT__ <<
"\n" << ss.str();
7592 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7593 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7613 void ConfigurationGUISupervisor::handleTableGroupsXML(
HttpXmlDocument& xmlOut,
7617 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7623 if(!cfgMgr->getAllGroupInfo().size() ||
7624 cfgMgr->getAllGroupInfo().begin()->second.latestKeyGroupTypeString_ ==
"" ||
7625 cfgMgr->getAllGroupInfo().begin()->second.latestKeyGroupTypeString_ ==
7626 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)
7628 __SUP_COUT__ <<
"Group Info cache appears empty. Attempting to regenerate."
7638 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
7640 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7643 std::string groupName;
7644 std::string groupString, groupTypeString, groupComment, groupCreationTime,
7646 for(
auto& groupInfo : allGroupInfo)
7648 groupName = groupInfo.first;
7649 if(groupInfo.second.keys_.size() == 0)
7651 __SUP_COUT__ <<
"Group name '" << groupName
7652 <<
"' found, but no keys so ignoring." << __E__;
7656 groupKey = *(groupInfo.second.keys_.rbegin());
7658 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7659 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupKey <<
"'/>" << __E__;
7662 xmlOut.dataSs_ <<
"<TableGroupType value='"
7663 << groupInfo.second.latestKeyGroupTypeString_ <<
"'/>" << __E__;
7664 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7666 groupInfo.second.latestKeyGroupComment_,
7669 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7670 << groupInfo.second.latestKeyGroupAuthor_ <<
"'/>" << __E__;
7671 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7672 << groupInfo.second.latestKeyGroupCreationTime_ <<
"'/>" << __E__;
7690 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
7692 for(
auto& memberPair : groupInfo.second.latestKeyMemberMap_)
7694 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
7696 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
7703 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
7708 for(
auto& keyInSet : groupInfo.second.keys_)
7710 if(keyInSet == groupKey)
7713 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7714 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
7719 bool loadingHistoricalInfo =
false;
7720 if(loadingHistoricalInfo)
7739 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7740 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7742 <<
")' to extract group comment and type." << __E__;
7745 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
7747 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7751 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
7753 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
7763 xmlOut.dataSs_ <<
"<TableGroupType value='"
7764 << groupInfo.second.latestKeyGroupTypeString_ <<
"'/>"
7766 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7769 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7772 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7789 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
7794 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
7796 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7811 void ConfigurationGUISupervisor::handleTablesXML(
HttpXmlDocument& xmlOut,
7814 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->
getActiveVersions().size() == 0)
7816 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
7826 xercesc::DOMElement* parentEl;
7827 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
7830 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
7831 for(
const auto& tablePair : allTableInfo)
7832 orderedTableSet.emplace(tablePair.first);
7836 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
7838 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
7841 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
7843 for(
const auto& orderedTableName : orderedTableSet)
7846 std::map<std::string, TableInfo>::const_iterator it =
7847 allTableInfo.find(orderedTableName);
7848 if(it == allTableInfo.end())
7850 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
7859 xmlOut.addTextElementToData(
"TableName", it->first);
7860 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
7863 if(versionAliases.find(it->first) != versionAliases.end())
7864 for(
auto& aliasVersion : versionAliases[it->first])
7865 if(it->second.versions_.find(aliasVersion.second) !=
7866 it->second.versions_.end())
7872 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
7890 for(
auto& version : it->second.versions_)
7906 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
7909 const std::string& modifiedTables)
7911 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
7914 setupActiveTablesXML(
7915 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
7917 std::map<std::string ,
7918 std::map<std::string , std::vector<std::string >>>
7919 nodeTypeToObjectMap;
7920 std::map<std::string , std::string >
7923 std::vector<std::string > artdaqSupervisorInfo;
7925 std::string artdaqSupervisorName;
7927 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap, artdaqSupervisorInfo);
7929 if(artdaqSupervisorInfo.size() != 4 )
7931 __SUP_COUT__ <<
"No artdaq supervisor found." << __E__;
7935 __SUP_COUT__ <<
"========== "
7936 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
7938 unsigned int paramIndex = 0;
7940 auto parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
7941 artdaqSupervisorInfo[paramIndex++]);
7943 std::string typeString =
"artdaqSupervisor";
7946 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
7948 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
7950 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
7952 for(
auto& subsystem : info.subsystems)
7954 typeString =
"subsystem";
7956 __SUP_COUT__ <<
"\t\t"
7957 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
7958 << subsystem.second.label <<
"'" << __E__;
7962 typeString +
"-id", std::to_string(subsystem.first), parentEl);
7965 std::to_string(subsystem.second.sources.size()),
7970 std::to_string(subsystem.second.destination),
7975 __SUP_COUT__ <<
"========== "
7976 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
7978 for(
auto& nameTypePair : nodeTypeToObjectMap)
7980 typeString = nameTypePair.first;
7982 __SUP_COUT__ <<
"\t"
7983 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
7986 for(
auto& artdaqNode : nameTypePair.second)
7988 __SUP_COUT__ <<
"\t\t"
7989 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
7992 if(artdaqNode.second.size() < 2)
7994 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
7995 <<
"' " << typeString <<
" - please notify admins!" << __E__;
8003 if(artdaqNode.second.size() > paramIndex)
8005 __SUP_COUTT__ <<
"\t\t\t"
8006 <<
"-multinode: " << artdaqNode.second[paramIndex] << __E__;
8008 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
8010 if(artdaqNode.second.size() > paramIndex)
8012 __SUP_COUTT__ <<
"\t\t\t"
8013 <<
"-nodefixedwidth: " << artdaqNode.second[paramIndex]
8016 artdaqNode.second[paramIndex++],
8019 if(artdaqNode.second.size() > paramIndex)
8021 __SUP_COUTT__ <<
"\t\t\t"
8022 <<
"-hostarray: " << artdaqNode.second[paramIndex] << __E__;
8024 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
8026 if(artdaqNode.second.size() > paramIndex)
8028 __SUP_COUTT__ <<
"\t\t\t"
8029 <<
"-hostfixedwidth: " << artdaqNode.second[paramIndex]
8032 artdaqNode.second[paramIndex++],
8037 __SUP_COUTT__ <<
"\t\t\t"
8038 <<
"-status: " << artdaqNode.second[paramIndex] << __E__;
8040 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
8041 __SUP_COUTT__ <<
"\t\t\t"
8042 <<
"-hostname: " << artdaqNode.second[paramIndex] << __E__;
8044 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
8045 __SUP_COUTT__ <<
"\t\t\t"
8046 <<
"-subsystem: " << artdaqNode.second[paramIndex] << __E__;
8048 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
8052 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
8063 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
8064 const std::string& nodeString,
8065 const std::string& subsystemString,
8068 const std::string& modifiedTables)
8070 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
8073 setupActiveTablesXML(
8074 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8077 std::map<std::string ,
8078 std::map<std::string , std::vector<std::string >>>
8079 nodeTypeToObjectMap;
8085 std::map<std::string , std::string >
8086 nodeTypeToStringMap;
8091 for(
auto& typePair : nodeTypeToStringMap)
8093 if(typePair.first ==
"")
8098 nodeTypeToObjectMap.emplace(
8100 std::map<std::string ,
8101 std::vector<std::string /*property*/>>()));
8103 std::map<std::string , std::string >
8104 nodeRecordToStringMap;
8107 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
8111 for(
auto& nodePair : nodeRecordToStringMap)
8113 if(nodePair.first ==
"")
8118 std::vector<std::string > nodePropertyVector;
8121 nodePair.second, nodePropertyVector, {
','});
8126 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
8131 nodePropertyVector[i] =
8135 nodeTypeToObjectMap[typePair.first].emplace(
8137 nodePropertyVector));
8143 std::map<std::string , std::string >
8150 std::map<std::string , std::string >
8151 tmpSubsystemObjectMap;
8153 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
8158 for(
auto& subsystemPair : tmpSubsystemObjectMap)
8163 subsystemObjectMap.emplace(
8170 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
8172 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
8182 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
8186 const std::string& contextGroupName ,
8189 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8192 const std::string& finalContextGroupName =
8194 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8198 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8200 const std::string& finalConfigGroupName =
8201 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8203 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8208 std::stringstream layoutPath;
8209 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8210 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8211 << finalConfigGroupKey <<
".dat";
8213 fp = fopen(layoutPath.str().c_str(),
"r");
8216 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8217 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
8218 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
8222 __SUP_COUTV__(layoutPath.str());
8227 std::stringstream layoutPath;
8228 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8229 <<
"_" << finalContextGroupKey <<
".dat";
8230 __SUP_COUTV__(layoutPath.str());
8232 fp = fopen(layoutPath.str().c_str(),
"r");
8235 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8236 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
8240 __SUP_COUTV__(layoutPath.str());
8247 const size_t maxLineSz = 1000;
8248 char line[maxLineSz];
8249 if(!fgets(line, maxLineSz, fp))
8258 unsigned int rows, cols;
8260 sscanf(line,
"%u %u", &rows, &cols);
8262 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
8264 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
8265 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
8268 char name[maxLineSz];
8269 char type[maxLineSz];
8271 while(fgets(line, maxLineSz, fp))
8274 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
8276 xmlOut.addTextElementToData(
"node-type", type);
8277 xmlOut.addTextElementToData(
"node-name", name);
8278 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
8279 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
8293 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
8296 const std::string& layoutString,
8297 const std::string& contextGroupName,
8300 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8302 const std::string& finalContextGroupName =
8304 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8308 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8310 const std::string& finalConfigGroupName =
8311 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8313 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8315 __SUP_COUTV__(layoutString);
8317 std::stringstream layoutPath;
8318 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8319 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8320 << finalConfigGroupKey <<
".dat";
8321 __SUP_COUTV__(layoutPath.str());
8326 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
8328 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
8332 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
8335 __SUP_SS__ <<
"Could not open layout file for writing for '"
8336 << finalContextGroupName <<
"(" << finalContextGroupKey <<
") + "
8337 << finalConfigGroupName <<
"(" << finalConfigGroupKey
8338 <<
")': " << layoutPath.
str() << __E__;
8345 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
8348 for(
unsigned int i = 2; i < fields.size(); i += 4)
8351 fields[i + 0].c_str(),
8352 fields[i + 1].c_str(),
8353 fields[i + 2].c_str(),
8354 fields[i + 3].c_str());
8362 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
8366 std::string targetSubsystem )
8372 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8375 for(
auto subsystem : children)
8377 __SUP_COUTV__(subsystem.first);
8381 std::string userPath =
8382 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8383 __SUP_COUTV__(userPath);
8386 catch(
const std::runtime_error& e)
8388 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
8389 "(assuming the subsystem information map is not setup in "
8390 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8391 <<
") -- here is the error: \n"
8392 << e.what() << __E__;
8399 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8401 for(
auto subsystem : children)
8403 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
8406 xercesc::DOMElement* parent =
8407 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
8412 std::string filename, userDataPath;
8413 std::string username, hostname;
8415 std::map<std::string ,
8417 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
8418 subsystem.first, &userDataPath, &hostname, &username);
8420 for(
const auto& retPair : retMap)
8423 retPair.second.first,
8426 retPair.second.second.toString(),
8430 std::vector<std::string> filenameTypes = {
"Configured",
8434 "ActivatedBackbone",
8435 "ActivatedIterator"};
8437 std::vector<std::string> filenames = {
8438 FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE,
8439 FSM_LAST_STARTED_GROUP_ALIAS_FILE,
8440 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
8441 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
8442 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
8443 ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE};
8445 std::string userPath =
8446 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8448 std::string cmdResult;
8449 for(
unsigned int i = 0; i < filenames.size(); ++i)
8451 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
8452 __SUP_COUTV__(filename);
8454 std::string tmpSubsystemFilename =
8455 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
8456 "." + subsystem.first;
8457 __SUP_COUTV__(tmpSubsystemFilename);
8459 if(splitPath.size() == 2)
8463 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
8464 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
8465 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
8469 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
8470 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
8471 tmpSubsystemFilename +
" 2>&1")
8474 else if(splitPath.size() == 1)
8477 " 2>/dev/null; cp " + filename +
" " +
8478 tmpSubsystemFilename +
" 2>&1; cat " +
8479 tmpSubsystemFilename +
" 2>&1")
8483 __SUP_COUTV__(cmdResult);
8484 std::string timeString;
8487 filenames[i] +
"." + subsystem.first, timeString);
8491 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
8493 theGroup.second.toString(),
8496 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
8501 catch(
const std::runtime_error& e)
8504 <<
"An error occurred handling subsystem active groups (Please check the "
8505 "subsystem user data path information map setup in the Context group table "
8506 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8507 <<
") -- here is the error: \n"
8508 << e.what() << __E__;
8514 void ConfigurationGUISupervisor::handleGroupDiff(
8517 const std::string& groupName,
8520 const std::string& diffGroupNameInput )
8526 std::string diffGroupName;
8529 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8530 <<
") with the active group." << __E__;
8533 if(diffGroupNameInput ==
"")
8534 diffGroupName = groupName;
8536 diffGroupName = diffGroupNameInput;
8538 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8539 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
8545 std::map<std::string ,
TableVersion > memberMap, diffMemberMap;
8546 std::string groupType, accumulateErrors;
8547 std::stringstream diffReport;
8548 bool noDifference =
true;
8567 std::map<std::string , std::pair<std::string, TableGroupKey>>
8574 __SUP_COUTV__(groupType);
8576 if(activeGroups.find(groupType) == activeGroups.end() ||
8577 activeGroups.at(groupType).first ==
"" ||
8578 activeGroups.at(groupType).second.isInvalid())
8580 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
8581 <<
".' Please check the expected active configuration groups "
8582 "for errors (going to 'System View' of the Config App may "
8588 __SUP_COUT__ <<
"active " << groupType <<
" group is "
8589 << activeGroups.at(groupType).first <<
"("
8590 << activeGroups.at(groupType).second <<
")" << __E__;
8592 diffReport <<
"This difference report is between " << groupType
8593 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
8594 <<
" and active group <b>'" << activeGroups.at(groupType).first
8595 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8598 activeGroups.at(groupType).second,
8608 diffReport <<
"\n\n"
8609 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8610 << memberMap.size() <<
" member tables</b>, and "
8611 <<
"'" << activeGroups.at(groupType).first <<
"("
8612 << activeGroups.at(groupType).second <<
")' has <b>"
8613 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8617 diffReport <<
"This difference report is between group <b>'" << groupName
8618 <<
"(" << groupKey <<
")'</b>"
8619 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
8620 <<
")'</b>." << __E__;
8633 diffReport <<
"\n\n"
8634 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8635 << memberMap.size() <<
" member tables</b>, and "
8636 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
8637 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8642 diffReport <<
"<INDENT><ol>";
8644 unsigned int tableDifferences = 0;
8646 for(
auto& member : memberMap)
8648 if(diffMemberMap.find(member.first) == diffMemberMap.end())
8650 diffReport <<
"\n\n<li>"
8651 <<
"Table <b>" << member.first <<
"-v" << member.second
8652 <<
"</b> not found in active group."
8653 <<
"</li>" << __E__;
8654 noDifference =
false;
8659 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
8660 <<
" ... " << member.first <<
"-v"
8661 << diffMemberMap.at(member.first) << __E__;
8663 if(member.second == diffMemberMap.at(member.first))
8666 diffReport <<
"\n\n<li>"
8667 <<
"Table <b>" << member.first <<
" v" << member.second
8668 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
8669 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
8670 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
8674 diffReport <<
"<ul>";
8675 std::map<std::string , std::vector<std::string >>
8678 diffMemberMap.at(member.first),
8683 noDifference =
false;
8686 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
8687 for(
auto& modifiedRecord : modifiedRecords)
8690 "RecordWithDiff", modifiedRecord.first, parentEl);
8691 for(
auto& modifiedColumn : modifiedRecord.second)
8693 "ColNameWithDiff", modifiedColumn, recordParentEl);
8696 diffReport <<
"</ul></li>";
8700 for(
auto& diffMember : diffMemberMap)
8702 if(memberMap.find(diffMember.first) == memberMap.end())
8705 diffReport <<
"\n\n<li>"
8706 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
8707 << diffMember.second <<
"</b> not found in '" << groupName
8708 <<
"(" << groupKey <<
")'."
8709 <<
"</li>" << __E__;
8711 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
8712 <<
") Table <b>" << diffMember.first <<
"-v"
8713 << diffMember.second <<
"</b> not found in '" << groupName
8714 <<
"(" << groupKey <<
")'."
8715 <<
"</li>" << __E__;
8717 noDifference =
false;
8722 diffReport <<
"\n</ol></INDENT>";
8727 diffReport <<
"\n\nNo difference found between "
8728 <<
"<b>'" << groupName <<
"(" << groupKey
8729 <<
")'</b> and active group "
8730 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8731 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8733 diffReport <<
"\n\n<b>" << tableDifferences
8734 <<
"</b> member table differences identified between "
8735 <<
"<b>'" << groupName <<
"(" << groupKey
8736 <<
")'</b> and active group "
8737 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8738 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8743 diffReport <<
"\n\nNo difference found between "
8744 <<
"<b>'" << groupName <<
"(" << groupKey
8745 <<
")'</b> and group "
8746 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8749 diffReport <<
"\n\n<b>" << tableDifferences
8750 <<
"</b> member table differences identified between "
8751 <<
"<b>'" << groupName <<
"(" << groupKey
8752 <<
")'</b> and group "
8753 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8757 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8758 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8760 catch(
const std::runtime_error& e)
8762 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
8763 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
8764 <<
")" << __E__ << e.what() << __E__;
8771 void ConfigurationGUISupervisor::handleTableDiff(
HttpXmlDocument& xmlOut,
8773 const std::string& tableName,
8777 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
8787 std::string localAccumulatedErrors =
"";
8791 &localAccumulatedErrors,
8794 if(localAccumulatedErrors !=
"")
8795 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8797 catch(std::runtime_error& e)
8799 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
8800 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8801 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8803 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8807 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
8812 catch(
const std::exception& e)
8814 ss <<
"Exception message: " << e.what();
8820 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8821 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8827 std::string localAccumulatedErrors =
"";
8831 &localAccumulatedErrors,
8834 if(localAccumulatedErrors !=
"")
8835 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8837 catch(std::runtime_error& e)
8839 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
8840 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8841 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8843 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8847 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
8852 catch(
const std::exception& e)
8854 ss <<
"Exception message: " << e.what();
8860 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8861 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8864 bool noDifference =
true;
8865 std::stringstream diffReport;
8867 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
8868 <<
" and v" << vB <<
"</b>." << __E__;
8870 diffReport <<
"<INDENT>";
8871 diffReport <<
"<ul>";
8872 std::map<std::string , std::vector<std::string >>
8875 noDifference =
false;
8876 diffReport <<
"</ul></INDENT>";
8878 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8879 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8885 void ConfigurationGUISupervisor::testXDAQContext()
8889 __SUP_COUT__ <<
"Attempting test activation of the context group." << __E__;
8892 catch(
const std::runtime_error& e)
8895 <<
"The test activation of the context group failed. Ignoring error: \n"
8896 << e.what() << __E__;
8900 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
static void setAndActivateARTDAQSystem(ConfigurationManagerRW *cfgMgr, const std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, const std::map< std::string, std::string > &subsystemObjectMap)
static const ARTDAQInfo & getARTDAQSystem(ConfigurationManagerRW *cfgMgr, std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, std::map< std::string, std::string > &subsystemObjectMap, std::vector< std::string > &artdaqSupervisoInfo)
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
virtual void setSupervisorPropertyDefaults(void) override
ConfigurationGUISupervisor(xdaq::ApplicationStub *s)
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
void clearAllCachedVersions(void)
const std::map< std::string, TableInfo > & getAllTableInfo(bool refresh=false, std::string *accumulatedWarnings=0, const std::string &errorFilterName="", bool getGroupKeys=false, bool getGroupInfo=false, bool initializeActiveGroups=false)
TableVersion copyViewToCurrentColumns(const std::string &tableName, TableVersion sourceVersion)
TableGroupKey saveNewTableGroup(const std::string &groupName, std::map< std::string, TableVersion > &groupMembers, const std::string &groupComment=TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT, std::map< std::string, std::string > *groupAliases=0)
void activateTableGroup(const std::string &tableGroupName, TableGroupKey tableGroupKey, std::string *accumulatedTreeErrors=0, std::string *groupTypeString=0)
const GroupInfo & getGroupInfo(const std::string &groupName)
void clearCachedVersions(const std::string &tableName)
const std::string & getUsername(void) const
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
void eraseTemporaryVersion(const std::string &tableName, TableVersion targetVersion=TableVersion())
TableBase * getVersionedTableByName(const std::string &tableName, TableVersion version, bool looseColumnMatching=false, std::string *accumulatedErrors=0, bool getRawData=false)
static void loadTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKey, std::shared_ptr< ots::GroupInfo > theGroupInfo, std::shared_ptr< std::atomic< bool >> theThreadDone)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
static const unsigned int PROCESSOR_COUNT
void restoreActiveTableGroups(bool throwErrors=false, const std::string &pathToActiveGroupsFile="", ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, std::string *accumulatedWarnings=0)
std::map< std::string, std::pair< std::string, TableGroupKey > > getActiveTableGroups(void) const
std::map< std::string, TableVersion > getActiveVersions(void) const
void copyTableGroupFromCache(const ConfigurationManager &cacheConfigMgr, const std::map< std::string, TableVersion > &groupMembers, const std::string &configGroupName="", const TableGroupKey &tableGroupKey=TableGroupKey(TableGroupKey::INVALID), bool doActivate=false, bool ignoreVersionTracking=false)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
static const std::set< std::string > contextMemberNames_
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
static const std::string & getTypeNameOfGroup(const std::map< std::string, TableVersion > &memberMap)
void destroyTableGroup(const std::string &theGroup="", bool onlyDeactivate=false)
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
TableGroupKey loadConfigurationBackbone(void)
const TableBase * getTableByName(const std::string &configurationName) const
static std::pair< std::string, TableGroupKey > loadGroupNameAndKey(const std::string &fileName, std::string &returnedTimeString)
static void getConfigurationStatusXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &username)
static void handleGetTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, TableGroupKey groupKey, bool ignoreWarnings=false, bool cacheOnly=false)
static TableVersion saveModifiedVersionXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion originalVersion, bool makeTemporary, TableBase *config, TableVersion temporaryModifiedVersion, bool ignoreDuplicates=false, bool lookForEquivalent=false)
static void handleCreateTableXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion version, bool makeTemporary, const std::string &data, const int &dataOffset, const std::string &author, const std::string &comment, bool sourceTableAsIs, bool lookForEquivalent)
static void handleCreateTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, const std::string &configList, bool allowDuplicates=false, bool ignoreWarnings=false, const std::string &groupComment="", bool lookForEquivalent=false)
bool isUIDNode(void) const
const TableVersion & getTableVersion(void) const
bool isDisconnected(void) const
const std::string & getAuthor(void) const
const std::string & getComment(void) const
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
const std::string & getTableName(void) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const std::string & getChildLinkIndex(void) const
const std::string & getDisconnectedTableName(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > getFixedChoices(void) const
bool isLinkNode(void) const
std::vector< ConfigurationTree::RecordField > getCommonFields(const std::vector< std::string > &recordList, const std::vector< std::string > &fieldAcceptList, const std::vector< std::string > &fieldRejectList, unsigned int depth=-1, bool autoSelectFilterFields=false) const
bool isValueNode(void) const
std::set< std::string > getUniqueValuesForField(const std::vector< std::string > &recordList, const std::string &fieldName, std::string *fieldGroupIDChildLinkIndex=0) const
const std::string & getValueType(void) const
bool isGroupLinkNode(void) const
const std::string & getFieldTableName(void) const
const std::string & getDisconnectedLinkID(void) const
const std::string & getParentTableName(void) const
bool isUIDLinkNode(void) const
const unsigned int & getFieldColumn(void) const
const std::string & getTableName(void) const
TableVersion createTemporaryView(TableVersion sourceViewVersion=TableVersion(), TableVersion destTemporaryViewVersion=TableVersion::getNextTemporaryVersion())
bool diffTwoVersions(TableVersion v1, TableVersion v2, std::stringstream *diffReport=0, std::map< std::string, std::vector< std::string >> *v1ModifiedRecords=0) const
TableVersion mergeViews(const TableView &sourceViewA, const TableView &sourceViewB, TableVersion destinationVersion, const std::string &author, const std::string &mergeApproach, std::map< std::pair< std::string, std::string >, std::string > &uidConversionMap, std::map< std::pair< std::string, std::pair< std::string, std::string > >, std::string > &groupidConversionMap, bool fillRecordConversionMaps, bool applyRecordConversionMaps, bool generateUniqueDataColumns=false, std::stringstream *mergeRepoert=nullptr)
static std::string convertToCaps(std::string &str, bool isConfigName=false)
TableView * getTemporaryView(TableVersion temporaryVersion)
const TableVersion & getViewVersion(void) const
void print(std::ostream &out=std::cout) const
std::string toString(void) const
bool isInvalid(void) const
static std::string getFullGroupString(const std::string &groupName, const TableGroupKey &key, const std::string &preKey="_v", const std::string &postKey="")
bool isMockupVersion(void) const
std::string toString(void) const
bool isInvalid(void) const
bool isScratchVersion(void) const
bool isTemporaryVersion(void) const
static const std::string DATATYPE_NUMBER
static std::map< std::pair< std::string, std::string >, std::string > getAllDefaultsForGUI(void)
static const std::string & getMaxDefaultValue(const std::string &dataType)
static const std::string & getMinDefaultValue(const std::string &dataType)
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
bool isEntryInGroup(const unsigned int &row, const std::string &childLinkIndex, const std::string &groupNeedle) const
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int getColStatus(void) const
unsigned int getLinkGroupIDColumn(const std::string &childLinkIndex) const
bool removeRowFromGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID, bool deleteRowIfNoGroupLeft=false)
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
void addRowToGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID)
std::string getValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
void getValue(T &value, unsigned int row, unsigned int col, bool doConvertEnvironmentVariables=true) const
unsigned int getColUID(void) const
bool setURIEncodedValue(const std::string &value, const unsigned int &row, const unsigned int &col, const std::string &author="")
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
void setURIEncodedComment(const std::string &uriComment)
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
static std::string convertEnvironmentVariables(const std::string &data)
static bool isNumber(const std::string &stringToCheck)
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string decodeURIComponent(const std::string &data)