1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
3 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq-core/Macros/CoutMacros.h"
5 #include "otsdaq-core/MessageFacility/MessageFacility.h"
6 #include "otsdaq-core/TablePlugins/IterateTable.h"
7 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
9 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
10 #include <boost/stacktrace.hpp>
13 #include "otsdaq-core/TablePlugins/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")
40 ConfigurationGUISupervisor::ConfigurationGUISupervisor(xdaq::ApplicationStub* stub)
41 : CoreSupervisorBase(stub)
43 __SUP_COUT__ <<
"Constructor started." << __E__;
45 INIT_MF(
"ConfigurationGUI");
48 __SUP_COUT__ <<
"Constructor complete." << __E__;
52 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
55 void ConfigurationGUISupervisor::init(
void)
57 __SUP_COUT__ <<
"Initializing..." << __E__;
59 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
67 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
68 "will not launch when this test fails. "
69 <<
"Check the active context group from within Wizard Mode."
75 void ConfigurationGUISupervisor::destroy(
void)
78 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
79 userConfigurationManagers_.begin();
80 it != userConfigurationManagers_.end();
86 userConfigurationManagers_.clear();
90 if(ConfigurationInterface::getInstance(
true) != 0)
91 delete ConfigurationInterface::getInstance(
true);
95 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
97 cgicc::Cgicc cgiIn(in);
98 std::string configWindowName =
99 CgiDataUtilities::getData(cgiIn,
"configWindowName");
100 if(configWindowName ==
"tableEditor")
101 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
102 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
103 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
104 if(configWindowName ==
"iterate")
105 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
106 "src='/WebPath/html/Iterate.html?urn="
107 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
109 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
110 "src='/WebPath/html/ConfigurationGUI.html?urn="
111 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
117 void ConfigurationGUISupervisor::setSupervisorPropertyDefaults(
void)
119 CorePropertySupervisorBase::setSupervisorProperty(
120 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
121 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
122 "deleteTableInfo=255");
123 CorePropertySupervisorBase::setSupervisorProperty(
124 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
131 void ConfigurationGUISupervisor::forceSupervisorPropertyValues()
133 CorePropertySupervisorBase::setSupervisorProperty(
134 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
136 CorePropertySupervisorBase::setSupervisorProperty(
137 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
142 void ConfigurationGUISupervisor::request(
const std::string& requestType,
144 HttpXmlDocument& xmlOut,
145 const WebUsers::RequestUserInfo& userInfo)
try
198 std::string refresh = CgiDataUtilities::getData(cgiIn,
"refresh");
202 ConfigurationManagerRW* cfgMgr = refreshUserSession(
203 userInfo.username_, userInfo.activeUserSessionIndex_, (refresh ==
"1"));
205 if(requestType ==
"saveTableInfo")
207 std::string tableName =
208 CgiDataUtilities::getData(cgiIn,
"tableName");
209 std::string columnCSV =
210 CgiDataUtilities::postData(cgiIn,
"columnCSV");
211 std::string allowOverwrite =
212 CgiDataUtilities::getData(cgiIn,
"allowOverwrite");
213 std::string tableDescription =
214 CgiDataUtilities::postData(cgiIn,
"tableDescription");
215 std::string columnChoicesCSV =
216 CgiDataUtilities::postData(cgiIn,
"columnChoicesCSV");
221 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
222 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
223 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
224 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
225 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
227 if(!allSupervisorInfo_.isWizardMode())
229 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
230 xmlOut.addTextElementToData(
"Error", ss.str());
233 handleSaveTableInfoXML(xmlOut,
239 allowOverwrite ==
"1");
241 else if(requestType ==
"deleteTableInfo")
243 std::string tableName =
244 CgiDataUtilities::getData(cgiIn,
"tableName");
245 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
246 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
248 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
249 requestType ==
"flattenToSystemAliases")
252 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
253 __MOUT_WARN__ << requestType <<
" command received! " << __E__;
256 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
258 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
259 std::vector<std::string> hostnames;
262 if(requestType ==
"flattenToSystemAliases" &&
263 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
265 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
266 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
274 const XDAQContextTable* contextTable =
275 cfgMgr->__GET_CONFIG__(XDAQContextTable);
277 auto contexts = contextTable->getContexts();
279 for(
const auto& context : contexts)
286 for(i = 0; i < context.address_.size(); ++i)
287 if(context.address_[i] ==
'/')
289 hostnames.push_back(context.address_.substr(j));
290 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
295 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
299 __SUP_COUT_ERR__ <<
"\n" << ss.str();
304 if(hostnames.size() == 0)
306 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
307 "'... Is there a valid Context group activated?"
309 __SUP_COUT_ERR__ <<
"\n" << ss.str();
311 xmlOut.addTextElementToData(
"Error", ss.str());
314 for(
const auto& hostname : hostnames)
316 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
317 "/StartOTS_action_" + hostname +
".cmd");
318 FILE* fp = fopen(fn.c_str(),
"w");
321 if(requestType ==
"gatewayLaunchOTS")
322 fprintf(fp,
"LAUNCH_OTS");
323 else if(requestType ==
"gatewayLaunchWiz")
324 fprintf(fp,
"LAUNCH_WIZ");
325 else if(requestType ==
"flattenToSystemAliases")
327 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
335 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
388 else if(requestType ==
"versionTracking")
390 std::string type = CgiDataUtilities::getData(cgiIn,
"Type");
391 __SUP_COUT__ <<
"type: " << type << __E__;
394 xmlOut.addTextElementToData(
395 "versionTrackingStatus",
396 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
397 else if(type ==
"ON")
399 ConfigurationInterface::setVersionTrackingEnabled(
true);
400 xmlOut.addTextElementToData(
401 "versionTrackingStatus",
402 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
404 else if(type ==
"OFF")
406 ConfigurationInterface::setVersionTrackingEnabled(
false);
407 xmlOut.addTextElementToData(
408 "versionTrackingStatus",
409 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
412 else if(requestType ==
"getColumnTypes")
415 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
416 std::vector<std::string> allDataTypes =
417 TableViewColumnInfo::getAllDataTypesForGUI();
418 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
419 TableViewColumnInfo::getAllDefaultsForGUI();
421 for(
const auto& type : allTypes)
422 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
423 for(
const auto& dataType : allDataTypes)
424 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
426 for(
const auto& colDefault : allDefaults)
428 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
429 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
430 colDefault.first.second);
431 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
434 else if(requestType ==
"getGroupAliases")
439 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
441 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
442 bool wasError =
false;
447 cfgMgr->clearAllCachedVersions();
448 cfgMgr->restoreActiveTableGroups(
true);
450 catch(std::runtime_error& e)
452 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
454 __SUP_COUT_ERR__ <<
"\n" << ss.str();
455 xmlOut.addTextElementToData(
"Error", ss.str());
460 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
461 __SUP_COUT_ERR__ <<
"\n" << ss.str();
462 xmlOut.addTextElementToData(
"Error", ss.str());
467 handleGroupAliasesXML(xmlOut, cfgMgr);
469 else if(requestType ==
"setGroupAliasInActiveBackbone")
471 std::string groupAlias =
472 CgiDataUtilities::getData(cgiIn,
"groupAlias");
473 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
475 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
477 __SUP_COUT__ <<
"groupAlias: " << groupAlias << __E__;
478 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
479 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
481 handleSetGroupAliasInBackboneXML(xmlOut,
485 TableGroupKey(groupKey),
488 else if(requestType ==
"setVersionAliasInActiveBackbone")
490 std::string versionAlias =
491 CgiDataUtilities::getData(cgiIn,
"versionAlias");
492 std::string tableName =
493 CgiDataUtilities::getData(cgiIn,
"tableName");
494 std::string version = CgiDataUtilities::getData(cgiIn,
"version");
496 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
497 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
498 __SUP_COUT__ <<
"version: " << version << __E__;
500 handleSetVersionAliasInBackboneXML(xmlOut,
504 TableVersion(version),
507 else if(requestType ==
"setAliasOfGroupMembers")
509 std::string versionAlias =
510 CgiDataUtilities::getData(cgiIn,
"versionAlias");
511 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
513 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
515 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
516 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
517 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
519 handleAliasGroupMembersInBackboneXML(xmlOut,
523 TableGroupKey(groupKey),
526 else if(requestType ==
"getVersionAliases")
528 handleVersionAliasesXML(xmlOut, cfgMgr);
530 else if(requestType ==
"getTableGroups")
532 bool doNotReturnMembers =
533 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
537 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
538 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
540 else if(requestType ==
"getTableGroupType")
542 std::string tableList =
543 CgiDataUtilities::postData(cgiIn,
"tableList");
544 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
546 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
548 else if(requestType ==
"getTables")
550 std::string allowIllegalColumns =
551 CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
553 __SUP_COUT__ <<
"allowIllegalColumns: " << allowIllegalColumns << __E__;
555 handleTablesXML(xmlOut, cfgMgr, allowIllegalColumns ==
"1");
557 else if(requestType ==
"getContextMemberNames")
559 std::set<std::string> members = cfgMgr->getContextMemberNames();
561 for(
auto& member : members)
562 xmlOut.addTextElementToData(
"ContextMember", member);
564 else if(requestType ==
"getBackboneMemberNames")
566 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
568 for(
auto& member : members)
569 xmlOut.addTextElementToData(
"BackboneMember", member);
571 else if(requestType ==
"getIterateMemberNames")
573 std::set<std::string> members = cfgMgr->getIterateMemberNames();
575 for(
auto& member : members)
576 xmlOut.addTextElementToData(
"IterateMember", member);
578 else if(requestType ==
"getSpecificTableGroup")
580 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
582 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
584 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
585 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
587 handleGetTableGroupXML(xmlOut, cfgMgr, groupName, TableGroupKey(groupKey));
589 else if(requestType ==
"saveNewTableGroup")
591 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
593 bool ignoreWarnings =
594 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
595 bool allowDuplicates =
596 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
597 bool lookForEquivalent =
598 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
599 std::string tableList =
600 CgiDataUtilities::postData(cgiIn,
"tableList");
601 std::string comment =
602 CgiDataUtilities::getData(cgiIn,
"groupComment");
604 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
605 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
606 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
607 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
608 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
609 __SUP_COUT__ <<
"comment: " << comment << __E__;
611 handleCreateTableGroupXML(xmlOut,
620 else if(requestType ==
"getSpecificTable")
622 std::string tableName =
623 CgiDataUtilities::getData(cgiIn,
"tableName");
624 std::string versionStr = CgiDataUtilities::getData(cgiIn,
"version");
625 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
626 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
628 std::string allowIllegalColumns =
629 CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
630 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
632 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
633 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
636 TableVersion version;
637 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
638 std::string versionAlias;
640 if(allTableInfo.find(tableName) != allTableInfo.end())
642 if(versionStr ==
"" &&
643 allTableInfo.at(tableName).versions_.size())
644 version = *(allTableInfo.at(tableName).versions_.rbegin());
645 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
648 std::map<std::string ,
649 std::map<std::string , TableVersion>>
650 versionAliases = cfgMgr->getVersionAliases();
652 versionAlias = versionStr.substr(
653 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
664 if(versionAliases.find(tableName) != versionAliases.end() &&
665 versionAliases[tableName].find(versionStr.substr(
666 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())) !=
667 versionAliases[tableName].end())
669 version = versionAliases[tableName][versionStr.substr(
670 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())];
671 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
676 << versionStr.substr(
677 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
678 <<
"'was not found in active version aliases!" << __E__;
681 version = atoi(versionStr.c_str());
684 __SUP_COUT__ <<
"version: " << version << __E__;
686 handleGetTableXML(xmlOut,
689 TableVersion(version),
690 (allowIllegalColumns ==
"1"));
692 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
694 else if(requestType ==
"saveSpecificTable")
696 std::string tableName =
697 CgiDataUtilities::getData(cgiIn,
"tableName");
698 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
699 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
700 bool sourceTableAsIs =
701 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
702 bool lookForEquivalent =
703 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
704 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
705 std::string comment =
706 CgiDataUtilities::getData(cgiIn,
"tableComment");
708 std::string data = CgiDataUtilities::postData(cgiIn,
"data");
712 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
713 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
715 __SUP_COUT__ <<
"comment: " << comment << __E__;
716 __SUP_COUT__ <<
"data: " << data << __E__;
717 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
718 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
720 handleCreateTableXML(xmlOut,
723 TableVersion(version),
732 else if(requestType ==
"clearTableTemporaryVersions")
734 std::string tableName =
735 CgiDataUtilities::getData(cgiIn,
"tableName");
736 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
740 cfgMgr->eraseTemporaryVersion(tableName);
742 catch(std::runtime_error& e)
744 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
745 xmlOut.addTextElementToData(
746 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
750 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
751 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
754 else if(requestType ==
"clearTableCachedVersions")
756 std::string tableName =
757 CgiDataUtilities::getData(cgiIn,
"tableName");
758 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
763 cfgMgr->clearAllCachedVersions();
765 cfgMgr->clearCachedVersions(tableName);
767 cfgMgr->getAllTableInfo(
true );
769 catch(std::runtime_error& e)
771 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
772 xmlOut.addTextElementToData(
773 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
777 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
778 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
781 else if(requestType ==
"getTreeView")
783 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
784 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
785 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
786 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
787 std::string filterList = CgiDataUtilities::postData(cgiIn,
"filterList");
788 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
789 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
791 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
792 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
793 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
794 __SUP_COUT__ <<
"depth: " << depth << __E__;
795 __SUP_COUT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
796 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
797 __SUP_COUT__ <<
"filterList: " << filterList << __E__;
799 handleFillTreeViewXML(xmlOut,
802 TableGroupKey(tableGroupKey),
809 else if(requestType ==
"getTreeNodeCommonFields")
811 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
812 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
813 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
814 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
815 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
816 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
817 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
819 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
820 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
821 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
822 __SUP_COUT__ <<
"depth: " << depth << __E__;
825 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
826 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
827 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
829 handleFillTreeNodeCommonFieldsXML(xmlOut,
832 TableGroupKey(tableGroupKey),
839 else if(requestType ==
"getUniqueFieldValuesForRecords")
841 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
842 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
843 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
844 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
845 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
846 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
848 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
849 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
850 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
851 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
852 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
853 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
855 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
858 TableGroupKey(tableGroupKey),
864 else if(requestType ==
"getTreeNodeFieldValues")
866 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
867 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
868 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
869 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
870 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
871 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
873 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
874 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
875 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
876 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
877 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
878 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
880 handleFillGetTreeNodeFieldValuesXML(xmlOut,
883 TableGroupKey(tableGroupKey),
889 else if(requestType ==
"setTreeNodeFieldValues")
891 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
892 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
893 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
894 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
895 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
896 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
897 std::string valueList = CgiDataUtilities::postData(cgiIn,
"valueList");
899 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
900 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
901 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
902 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
903 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
904 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
905 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
907 handleFillSetTreeNodeFieldValuesXML(xmlOut,
910 TableGroupKey(tableGroupKey),
918 else if(requestType ==
"addTreeNodeRecords")
920 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
921 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
922 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
923 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
924 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
926 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
927 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
928 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
929 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
930 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
932 handleFillCreateTreeNodeRecordsXML(xmlOut,
935 TableGroupKey(tableGroupKey),
941 else if(requestType ==
"deleteTreeNodeRecords")
943 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
944 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
945 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
946 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
947 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
949 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
950 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
951 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
952 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
953 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
955 handleFillDeleteTreeNodeRecordsXML(xmlOut,
958 TableGroupKey(tableGroupKey),
963 else if(requestType ==
"getAffectedActiveGroups")
965 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
966 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
967 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
968 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
969 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
970 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
972 handleGetAffectedGroupsXML(
973 xmlOut, cfgMgr, groupName, TableGroupKey(groupKey), modifiedTables);
975 else if(requestType ==
"saveTreeNodeEdit")
977 std::string editNodeType = CgiDataUtilities::getData(cgiIn,
"editNodeType");
978 std::string targetTable = CgiDataUtilities::getData(cgiIn,
"targetTable");
979 std::string targetTableVersion =
980 CgiDataUtilities::getData(cgiIn,
"targetTableVersion");
981 std::string targetUID = CgiDataUtilities::getData(cgiIn,
"targetUID");
982 std::string targetColumn = CgiDataUtilities::getData(cgiIn,
"targetColumn");
983 std::string newValue = CgiDataUtilities::postData(cgiIn,
"newValue");
985 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
986 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
987 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
988 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
989 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
990 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
992 handleSaveTreeNodeEditXML(xmlOut,
995 TableVersion(targetTableVersion),
997 CgiDataUtilities::decodeURIComponent(targetUID),
998 CgiDataUtilities::decodeURIComponent(targetColumn),
1000 userInfo.username_);
1002 else if(requestType ==
"getLinkToChoices")
1004 std::string linkToTableName = CgiDataUtilities::getData(cgiIn,
"linkToTableName");
1005 std::string linkToTableVersion =
1006 CgiDataUtilities::getData(cgiIn,
"linkToTableVersion");
1007 std::string linkIdType = CgiDataUtilities::getData(cgiIn,
"linkIdType");
1008 std::string linkIndex = CgiDataUtilities::decodeURIComponent(
1009 CgiDataUtilities::getData(cgiIn,
"linkIndex"));
1010 std::string linkInitId = CgiDataUtilities::getData(cgiIn,
"linkInitId");
1012 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1013 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1014 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1015 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1016 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1018 handleGetLinkToChoicesXML(xmlOut,
1021 TableVersion(linkToTableVersion),
1026 else if(requestType ==
"activateTableGroup")
1028 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1029 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1030 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1032 __SUP_COUT__ <<
"Activating config: " << groupName <<
"(" << groupKey <<
")"
1034 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
1037 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1038 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1039 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1041 std::string accumulatedTreeErrors;
1044 cfgMgr->activateTableGroup(
1046 TableGroupKey(groupKey),
1049 : &accumulatedTreeErrors);
1051 catch(std::runtime_error& e)
1056 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1057 xmlOut.addTextElementToData(
1059 "Error activating config group '" + groupName +
"(" + groupKey +
")" +
1060 ".' Please see details below:\n\n" + std::string(e.what()));
1061 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1062 <<
" (" << groupKey <<
")" << __E__;
1065 cfgMgr->destroyTableGroup(groupName,
true);
1071 catch(cet::exception& e)
1077 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1078 xmlOut.addTextElementToData(
"Error",
1079 "Error activating config group '" + groupName +
1080 "(" + groupKey +
")" +
"!'\n\n" +
1081 std::string(e.what()));
1082 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1083 <<
" (" << groupKey <<
")" << __E__;
1086 cfgMgr->destroyTableGroup(groupName,
true);
1094 __SUP_COUT__ <<
"Error detected!" << __E__;
1098 if(accumulatedTreeErrors !=
"")
1099 xmlOut.addTextElementToData(
"Error",
1100 "Warnings were found when activating group '" +
1101 groupName +
"(" + groupKey +
")" +
1102 "'! Please see details below:\n\n" +
1103 accumulatedTreeErrors);
1105 else if(requestType ==
"getActiveTableGroups")
1107 else if(requestType ==
"copyViewToCurrentColumns")
1109 std::string tableName =
1110 CgiDataUtilities::getData(cgiIn,
"tableName");
1111 std::string sourceVersion = CgiDataUtilities::getData(cgiIn,
"sourceVersion");
1113 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1114 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1115 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1118 TableVersion newTemporaryVersion;
1122 newTemporaryVersion =
1123 cfgMgr->copyViewToCurrentColumns(tableName, TableVersion(sourceVersion));
1136 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1138 catch(std::runtime_error& e)
1140 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1141 xmlOut.addTextElementToData(
"Error",
1142 "Error copying view from '" + tableName +
"_v" +
1143 sourceVersion +
"'! " +
1144 std::string(e.what()));
1148 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1149 xmlOut.addTextElementToData(
1151 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1154 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1156 else if(requestType ==
"getLastTableGroups")
1158 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* gatewaySupervisor =
1159 allSupervisorInfo_.isWizardMode() ? allSupervisorInfo_.getWizardDescriptor()
1160 : allSupervisorInfo_.getGatewayDescriptor();
1162 std::string timeString;
1163 std::pair<std::string , TableGroupKey> theGroup =
1164 theRemoteWebUsers_.getLastConfigGroup(
1165 gatewaySupervisor,
"Configured", timeString);
1166 xmlOut.addTextElementToData(
"LastConfiguredGroupName", theGroup.first);
1167 xmlOut.addTextElementToData(
"LastConfiguredGroupKey", theGroup.second.toString());
1168 xmlOut.addTextElementToData(
"LastConfiguredGroupTime", timeString);
1169 theGroup = theRemoteWebUsers_.getLastConfigGroup(
1170 gatewaySupervisor,
"Started", timeString);
1171 xmlOut.addTextElementToData(
"LastStartedGroupName", theGroup.first);
1172 xmlOut.addTextElementToData(
"LastStartedGroupKey", theGroup.second.toString());
1173 xmlOut.addTextElementToData(
"LastStartedGroupTime", timeString);
1175 else if(requestType ==
"savePlanCommandSequence")
1177 std::string planName = CgiDataUtilities::getData(cgiIn,
"planName");
1178 std::string commands = CgiDataUtilities::postData(cgiIn,
"commands");
1180 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1181 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1182 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1184 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1185 __SUP_COUT__ <<
"planName: " << planName << __E__;
1186 __SUP_COUT__ <<
"commands: " << commands << __E__;
1187 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1188 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1190 handleSavePlanCommandSequenceXML(xmlOut,
1193 TableGroupKey(groupKey),
1199 else if(requestType ==
"mergeGroups")
1201 std::string groupANameContext =
1202 CgiDataUtilities::getData(cgiIn,
"groupANameContext");
1203 std::string groupAKeyContext =
1204 CgiDataUtilities::getData(cgiIn,
"groupAKeyContext");
1205 std::string groupBNameContext =
1206 CgiDataUtilities::getData(cgiIn,
"groupBNameContext");
1207 std::string groupBKeyContext =
1208 CgiDataUtilities::getData(cgiIn,
"groupBKeyContext");
1209 std::string groupANameConfig =
1210 CgiDataUtilities::getData(cgiIn,
"groupANameConfig");
1211 std::string groupAKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupAKeyConfig");
1212 std::string groupBNameConfig =
1213 CgiDataUtilities::getData(cgiIn,
"groupBNameConfig");
1214 std::string groupBKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupBKeyConfig");
1215 std::string mergeApproach = CgiDataUtilities::getData(cgiIn,
"mergeApproach");
1217 __SUP_COUTV__(groupANameContext);
1218 __SUP_COUTV__(groupAKeyContext);
1219 __SUP_COUTV__(groupBNameContext);
1220 __SUP_COUTV__(groupBKeyContext);
1221 __SUP_COUTV__(groupANameConfig);
1222 __SUP_COUTV__(groupAKeyConfig);
1223 __SUP_COUTV__(groupBNameConfig);
1224 __SUP_COUTV__(groupBKeyConfig);
1225 __SUP_COUTV__(mergeApproach);
1227 handleMergeGroupsXML(xmlOut,
1230 TableGroupKey(groupAKeyContext),
1232 TableGroupKey(groupBKeyContext),
1234 TableGroupKey(groupAKeyConfig),
1236 TableGroupKey(groupBKeyConfig),
1242 __SUP_SS__ <<
"requestType '" << requestType <<
"' request not recognized."
1244 __SUP_COUT__ <<
"\n" << ss.str();
1245 xmlOut.addTextElementToData(
"Error", ss.str());
1251 std::map<std::string , std::pair<std::string , TableGroupKey>>
1252 activeGroupMap = cfgMgr->getActiveTableGroups();
1254 for(
auto& type : activeGroupMap)
1256 xmlOut.addTextElementToData(type.first +
"-ActiveGroupName", type.second.first);
1257 xmlOut.addTextElementToData(type.first +
"-ActiveGroupKey",
1258 type.second.second.toString());
1264 xmlOut.addTextElementToData(
1266 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1273 catch(
const std::runtime_error& e)
1275 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1276 <<
".' Error: " << e.what() << __E__;
1277 __COUT_ERR__ <<
"\n" << ss.str();
1278 xmlOut.addTextElementToData(
"Error", ss.str());
1283 xmlOut.addTextElementToData(
1285 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1289 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1294 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1295 << requestType <<
".'" << __E__;
1296 __COUT_ERR__ <<
"\n" << ss.str();
1297 xmlOut.addTextElementToData(
"Error", ss.str());
1302 xmlOut.addTextElementToData(
1304 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1308 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1320 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1321 HttpXmlDocument& xmlOut,
1322 ConfigurationManagerRW* cfgMgr,
1323 const std::string& rootGroupName,
1324 const TableGroupKey& rootGroupKey,
1325 const std::string& modifiedTables)
try
1335 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1336 cfgMgr->getActiveTableGroups();
1340 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT]
1341 .second.isInvalid())
1343 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1344 if(cfgMgr->getFailedTableGroups().find(
1345 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT) !=
1346 cfgMgr->getFailedTableGroups().end())
1348 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1349 cfgMgr->getFailedTableGroups().at(
1350 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT);
1352 else if(cfgMgr->getFailedTableGroups().find(
1353 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1354 cfgMgr->getFailedTableGroups().end())
1356 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1357 cfgMgr->getFailedTableGroups().at(
1358 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1361 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION]
1362 .second.isInvalid())
1364 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1365 if(cfgMgr->getFailedTableGroups().find(
1366 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION) !=
1367 cfgMgr->getFailedTableGroups().end())
1369 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1370 cfgMgr->getFailedTableGroups().at(
1371 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION);
1373 else if(cfgMgr->getFailedTableGroups().find(
1374 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1375 cfgMgr->getFailedTableGroups().end())
1377 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1378 cfgMgr->getFailedTableGroups().at(
1379 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1383 __SUP_COUTV__(StringMacros::mapToString(consideredGroups));
1388 std::map<std::string , TableVersion > rootGroupMemberMap;
1390 cfgMgr->loadTableGroup(rootGroupName,
1393 &rootGroupMemberMap,
1401 const std::string& groupType = cfgMgr->getTypeNameOfGroup(rootGroupMemberMap);
1403 consideredGroups[groupType] =
1404 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1406 catch(
const std::runtime_error& e)
1409 if(rootGroupName.size())
1411 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1412 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1413 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1418 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1419 "name - assuming this was intentional."
1425 if(rootGroupName.size())
1427 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1428 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1433 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1434 "name - assuming this was intentional."
1438 std::map<std::string , TableVersion > modifiedTablesMap;
1439 std::map<std::string , TableVersion >::iterator
1440 modifiedTablesMapIt;
1442 std::istringstream f(modifiedTables);
1443 std::string table, version;
1444 while(getline(f, table,
','))
1446 getline(f, version,
',');
1447 modifiedTablesMap.insert(
1448 std::pair<std::string /*name*/, TableVersion /*version*/>(
1449 table, TableVersion(version)));
1451 __SUP_COUT__ << modifiedTables << __E__;
1452 for(
auto& pair : modifiedTablesMap)
1453 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1458 DOMElement* parentEl;
1459 std::string groupComment;
1460 for(
auto group : consideredGroups)
1462 if(group.second.second.isInvalid())
1465 __SUP_COUT__ <<
"Considering " << group.first <<
" group " << group.second.first
1466 <<
" (" << group.second.second <<
")" << __E__;
1470 std::map<std::string , TableVersion > memberMap;
1471 cfgMgr->loadTableGroup(group.second.first,
1472 group.second.second,
1482 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1484 for(
auto& table : memberMap)
1486 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1489 table.second != (*modifiedTablesMapIt).second)
1491 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1492 << (*modifiedTablesMapIt).second << __E__;
1494 memberMap[table.first] = (*modifiedTablesMapIt).second;
1500 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1501 xmlOut.addTextElementToParent(
"GroupName", group.second.first, parentEl);
1502 xmlOut.addTextElementToParent(
1503 "GroupKey", group.second.second.toString(), parentEl);
1504 xmlOut.addTextElementToParent(
"GroupComment", groupComment, parentEl);
1506 for(
auto& table : memberMap)
1508 xmlOut.addTextElementToParent(
"MemberName", table.first, parentEl);
1509 xmlOut.addTextElementToParent(
1510 "MemberVersion", table.second.toString(), parentEl);
1515 catch(std::runtime_error& e)
1517 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1518 xmlOut.addTextElementToData(
1519 "Error",
"Error getting affected groups! " + std::string(e.what()));
1523 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1524 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1535 void ConfigurationGUISupervisor::setupActiveTablesXML(
1536 HttpXmlDocument& xmlOut,
1537 ConfigurationManagerRW* cfgMgr,
1538 const std::string& groupName,
1539 const TableGroupKey& groupKey,
1540 const std::string& modifiedTables,
1542 bool doGetGroupInfo,
1543 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1544 bool outputActiveTables,
1545 std::string* accumulatedErrors)
try
1550 xmlOut.addTextElementToData(
"tableGroup", groupName);
1551 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.toString());
1553 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
1556 if(usingActiveGroups || refreshAll)
1558 __SUP_COUT__ <<
"Refreshing all table info..." << __E__;
1559 cfgMgr->getAllTableInfo(
true, accumulatedErrors);
1561 if(accumulatedErrors && *accumulatedErrors !=
"")
1562 __SUP_COUTV__(*accumulatedErrors);
1565 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
false);
1567 std::map<std::string , TableVersion > modifiedTablesMap;
1568 std::map<std::string , TableVersion >::iterator
1569 modifiedTablesMapIt;
1571 if(usingActiveGroups)
1574 __SUP_COUT__ <<
"Using active groups." << __E__;
1578 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
1581 std::string groupComment, groupAuthor, configGroupCreationTime;
1584 cfgMgr->loadTableGroup(groupName,
1590 doGetGroupInfo ? &groupComment : 0,
1591 doGetGroupInfo ? &groupAuthor : 0,
1592 doGetGroupInfo ? &configGroupCreationTime : 0);
1596 xmlOut.addTextElementToData(
"configGroupComment", groupComment);
1597 xmlOut.addTextElementToData(
"configGroupAuthor", groupAuthor);
1598 xmlOut.addTextElementToData(
"configGroupCreationTime",
1599 configGroupCreationTime);
1602 if(accumulatedErrors && *accumulatedErrors !=
"")
1603 __SUP_COUTV__(*accumulatedErrors);
1608 std::istringstream f(modifiedTables);
1609 std::string table, version;
1610 while(getline(f, table,
','))
1612 getline(f, version,
',');
1613 modifiedTablesMap.insert(
1614 std::pair<std::string /*name*/, TableVersion /*version*/>(
1615 table, TableVersion(version)));
1618 for(
auto& pair : modifiedTablesMap)
1619 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1624 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
1625 xmlOut.addTextElementToData(
"DefaultNoLink",
1626 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
1627 for(
auto& activePair : allActivePairs)
1629 if(outputActiveTables)
1630 xmlOut.addTextElementToData(
"ActiveTableName", activePair.first);
1634 if((modifiedTablesMapIt = modifiedTablesMap.find(activePair.first)) !=
1635 modifiedTablesMap.end())
1637 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
1638 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
1642 allTableInfo.at(activePair.first)
1643 .tablePtr_->setActiveView((*modifiedTablesMapIt).second);
1648 <<
"Modified table version v" << (*modifiedTablesMapIt).second
1649 <<
" failed. Reverting to v"
1650 << allTableInfo.at(activePair.first).tablePtr_->getView().getVersion()
1652 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
1653 xmlOut.addTextElementToData(
1655 "Error setting up active tables!\n\n" + std::string(ss.str()));
1659 if(outputActiveTables)
1661 xmlOut.addTextElementToData(
"ActiveTableVersion",
1662 allTableInfo.at(activePair.first)
1663 .tablePtr_->getView()
1666 xmlOut.addTextElementToData(
1667 "ActiveTableComment",
1668 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
1677 catch(std::runtime_error& e)
1679 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
1681 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1682 xmlOut.addTextElementToData(
"Error", ss.str());
1686 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
1687 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1688 xmlOut.addTextElementToData(
"Error", ss.str());
1706 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
1707 HttpXmlDocument& xmlOut,
1708 ConfigurationManagerRW* cfgMgr,
1709 const std::string& groupName,
1710 const TableGroupKey& groupKey,
1711 const std::string& startPath,
1712 const std::string& modifiedTables,
1713 const std::string& recordList,
1714 const std::string& author)
1717 setupActiveTablesXML(xmlOut,
1729 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
1730 TableBase* config = cfgMgr->getTableByName(targetNode.getTableName());
1732 __SUP_COUT__ << config->getTableName() << __E__;
1733 TableVersion temporaryVersion;
1742 bool firstSave =
true;
1745 TableView backupView;
1749 std::istringstream f(recordList);
1750 std::string recordUID;
1753 while(getline(f, recordUID,
','))
1755 recordUID = StringMacros::decodeURIComponent(recordUID);
1757 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
1761 if(!(temporaryVersion = targetNode.getTableVersion())
1762 .isTemporaryVersion())
1764 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
1766 temporaryVersion = config->createTemporaryView(temporaryVersion);
1767 cfgMgr->saveNewTable(targetNode.getTableName(),
1772 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
1776 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
1782 backupView.copy(config->getView(), temporaryVersion, author);
1791 unsigned int row = config->getViewP()->addRow(
1798 unsigned int col = config->getViewP()->getColStatus();
1799 config->getViewP()->setURIEncodedValue(
"1", row, col);
1806 config->getViewP()->setURIEncodedValue(
1807 recordUID, row, config->getViewP()->getColUID());
1815 config->getViewP()->init();
1819 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
1820 __SUP_COUT__ <<
"Before:" << __E__;
1821 config->getViewP()->print();
1822 config->getViewP()->copy(backupView, temporaryVersion, author);
1823 __SUP_COUT__ <<
"After:" << __E__;
1824 config->getViewP()->print();
1830 handleFillModifiedTablesXML(xmlOut, cfgMgr);
1832 catch(std::runtime_error& e)
1834 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
1836 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1837 xmlOut.addTextElementToData(
"Error", ss.str());
1841 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
1842 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1843 xmlOut.addTextElementToData(
"Error", ss.str());
1850 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
1851 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr)
try
1854 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
1855 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
1856 for(
auto& activePair : allActivePairs)
1858 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
1859 xmlOut.addTextElementToData(
"NewActiveTableVersion",
1860 allTableInfo.at(activePair.first)
1861 .tablePtr_->getView()
1864 xmlOut.addTextElementToData(
1865 "NewActiveTableComment",
1866 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
1869 catch(std::runtime_error& e)
1871 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
1872 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1873 xmlOut.addTextElementToData(
"Error", ss.str());
1877 __SUP_SS__ << (
"Error!\n\n") << __E__;
1878 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1879 xmlOut.addTextElementToData(
"Error", ss.str());
1897 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
1898 HttpXmlDocument& xmlOut,
1899 ConfigurationManagerRW* cfgMgr,
1900 const std::string& groupName,
1901 const TableGroupKey& groupKey,
1902 const std::string& startPath,
1903 const std::string& modifiedTables,
1904 const std::string& recordList)
1907 setupActiveTablesXML(xmlOut,
1919 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
1920 TableBase* config = cfgMgr->getTableByName(targetNode.getTableName());
1922 __SUP_COUT__ << config->getTableName() << __E__;
1923 TableVersion temporaryVersion;
1932 bool firstSave =
true;
1936 std::istringstream f(recordList);
1937 std::string recordUID;
1940 while(getline(f, recordUID,
','))
1942 recordUID = StringMacros::decodeURIComponent(recordUID);
1944 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
1948 if(!(temporaryVersion = targetNode.getTableVersion())
1949 .isTemporaryVersion())
1951 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
1953 temporaryVersion = config->createTemporaryView(temporaryVersion);
1954 cfgMgr->saveNewTable(targetNode.getTableName(),
1959 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
1963 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
1973 unsigned int row = config->getViewP()->findRow(
1974 config->getViewP()->getColUID(), recordUID);
1975 config->getViewP()->deleteRow(row);
1980 config->getViewP()->init();
1982 handleFillModifiedTablesXML(xmlOut, cfgMgr);
1984 catch(std::runtime_error& e)
1986 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
1987 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1988 xmlOut.addTextElementToData(
"Error", ss.str());
1992 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
1993 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1994 xmlOut.addTextElementToData(
"Error", ss.str());
2015 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2016 HttpXmlDocument& xmlOut,
2017 ConfigurationManagerRW* cfgMgr,
2018 const std::string& groupName,
2019 const TableGroupKey& groupKey,
2020 const std::string& startPath,
2021 const std::string& modifiedTables,
2022 const std::string& recordList,
2023 const std::string& fieldList,
2024 const std::string& valueList,
2025 const std::string& author)
2028 setupActiveTablesXML(xmlOut,
2043 std::vector<std::string > fieldPaths;
2046 std::istringstream f(fieldList);
2047 std::string fieldPath;
2048 while(getline(f, fieldPath,
','))
2050 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2052 __SUP_COUT__ << fieldList << __E__;
2053 for(
const auto& field : fieldPaths)
2054 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2057 std::vector<std::string > fieldValues;
2060 std::istringstream f(valueList);
2061 std::string fieldValue;
2062 while(getline(f, fieldValue,
','))
2064 fieldValues.push_back(
2070 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2071 fieldValues.push_back(
"");
2073 __SUP_COUT__ << valueList << __E__;
2074 for(
const auto& value : fieldValues)
2075 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2078 if(fieldPaths.size() != fieldValues.size())
2081 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2087 TableVersion temporaryVersion;
2088 std::istringstream f(recordList);
2089 std::string recordUID;
2092 while(getline(f, recordUID,
','))
2094 recordUID = StringMacros::decodeURIComponent(recordUID);
2098 DOMElement* parentEl =
2099 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2102 for(i = 0; i < fieldPaths.size(); ++i)
2104 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2105 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2109 ConfigurationTree targetNode =
2110 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2145 __SUP_COUT__ <<
"Getting table " << targetNode.getFieldTableName()
2149 config = cfgMgr->getTableByName(
2150 targetNode.getFieldTableName());
2151 if(!(temporaryVersion = config->getViewP()->getVersion())
2152 .isTemporaryVersion())
2156 config->createTemporaryView(config->getViewP()->getVersion());
2157 cfgMgr->saveNewTable(config->getTableName(),
2162 __SUP_COUT__ <<
"Created temporary version "
2163 << config->getTableName() <<
"-v" << temporaryVersion
2167 __SUP_COUT__ <<
"Using temporary version " << config->getTableName()
2168 <<
"-v" << temporaryVersion << __E__;
2172 config->getViewP()->setURIEncodedValue(fieldValues[i],
2173 targetNode.getFieldRow(),
2174 targetNode.getFieldColumn(),
2183 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2185 catch(std::runtime_error& e)
2187 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2189 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2190 xmlOut.addTextElementToData(
"Error", ss.str());
2194 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2195 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2196 xmlOut.addTextElementToData(
"Error", ss.str());
2215 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2216 HttpXmlDocument& xmlOut,
2217 ConfigurationManagerRW* cfgMgr,
2218 const std::string& groupName,
2219 const TableGroupKey& groupKey,
2220 const std::string& startPath,
2221 const std::string& modifiedTables,
2222 const std::string& recordList,
2223 const std::string& fieldList)
2226 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2233 std::vector<std::string > fieldPaths;
2236 std::istringstream f(fieldList);
2237 std::string fieldPath;
2238 while(getline(f, fieldPath,
','))
2240 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2242 __SUP_COUT__ << fieldList << __E__;
2243 for(
auto& field : fieldPaths)
2244 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2249 std::istringstream f(recordList);
2250 std::string recordUID;
2251 while(getline(f, recordUID,
','))
2253 recordUID = StringMacros::decodeURIComponent(recordUID);
2255 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2257 DOMElement* parentEl =
2258 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2261 for(
const auto& fieldPath : fieldPaths)
2263 __SUP_COUT__ <<
"fieldPath " << fieldPath << __E__;
2265 ConfigurationTree node =
2266 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
2268 xmlOut.addTextElementToParent(
"FieldPath", fieldPath, parentEl);
2270 xmlOut.addTextElementToParent(
2272 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath)
2273 .getValueAsString(
true ),
2279 catch(std::runtime_error& e)
2281 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
2283 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2284 xmlOut.addTextElementToData(
"Error", ss.str());
2288 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
2289 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2290 xmlOut.addTextElementToData(
"Error", ss.str());
2313 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
2314 HttpXmlDocument& xmlOut,
2315 ConfigurationManagerRW* cfgMgr,
2316 const std::string& groupName,
2317 const TableGroupKey& groupKey,
2318 const std::string& startPath,
2320 const std::string& modifiedTables,
2321 const std::string& recordList,
2322 const std::string& fieldList)
2325 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2329 DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
2333 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
2334 __SUP_COUT__ << ss.str();
2343 std::vector<ConfigurationTree::RecordField> retFieldList;
2346 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2347 if(startNode.isLinkNode() && startNode.isDisconnected())
2349 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
2350 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2356 std::vector<std::string > fieldAcceptList, fieldRejectList;
2361 std::istringstream f(fieldList);
2362 std::string fieldPath, decodedFieldPath;
2363 while(getline(f, fieldPath,
','))
2365 decodedFieldPath = StringMacros::decodeURIComponent(fieldPath);
2367 if(decodedFieldPath[0] ==
'!')
2368 fieldRejectList.push_back(decodedFieldPath.substr(1));
2370 fieldAcceptList.push_back(decodedFieldPath);
2372 __SUP_COUT__ << fieldList << __E__;
2373 for(
auto& field : fieldAcceptList)
2374 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
2375 for(
auto& field : fieldRejectList)
2376 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
2380 std::vector<std::string > records;
2381 if(recordList ==
"*")
2384 records = startNode.getChildrenNames();
2385 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2386 for(
auto& record : records)
2387 __SUP_COUT__ <<
"recordList " << record << __E__;
2389 else if(recordList !=
"")
2393 std::istringstream f(recordList);
2394 std::string recordStr;
2395 while(getline(f, recordStr,
','))
2397 records.push_back(StringMacros::decodeURIComponent(recordStr));
2399 __SUP_COUT__ << recordList << __E__;
2400 for(
auto& record : records)
2401 __SUP_COUT__ <<
"recordList " << record << __E__;
2405 retFieldList = startNode.getCommonFields(
2406 records, fieldAcceptList, fieldRejectList, depth);
2409 DOMElement* parentTypeEl;
2410 for(
const auto& fieldInfo : retFieldList)
2412 xmlOut.addTextElementToParent(
2413 "FieldTableName", fieldInfo.tableName_, parentEl);
2414 xmlOut.addTextElementToParent(
2415 "FieldColumnName", fieldInfo.columnName_, parentEl);
2416 xmlOut.addTextElementToParent(
2417 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
2418 xmlOut.addTextElementToParent(
2419 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
2420 xmlOut.addTextElementToParent(
2421 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
2422 xmlOut.addTextElementToParent(
"FieldColumnDefaultValue",
2423 fieldInfo.columnInfo_->getDefaultValue(),
2427 xmlOut.addTextElementToParent(
"FieldColumnDataChoices",
"", parentEl);
2430 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
2431 xmlOut.addTextElementToParent(
2432 "FieldColumnDataChoice",
2433 fieldInfo.columnInfo_->getDefaultValue(),
2435 for(
const auto& dataChoice : dataChoices)
2436 xmlOut.addTextElementToParent(
2437 "FieldColumnDataChoice", dataChoice, parentTypeEl);
2440 catch(std::runtime_error& e)
2442 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
2444 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2445 xmlOut.addTextElementToData(
"Error", ss.str());
2449 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
2450 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2451 xmlOut.addTextElementToData(
"Error", ss.str());
2483 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
2484 HttpXmlDocument& xmlOut,
2485 ConfigurationManagerRW* cfgMgr,
2486 const std::string& groupName,
2487 const TableGroupKey& groupKey,
2488 const std::string& startPath,
2489 const std::string& modifiedTables,
2490 const std::string& recordList,
2491 const std::string& fieldList)
2494 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2500 if(startPath ==
"/")
2503 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2504 if(startNode.isLinkNode() && startNode.isDisconnected())
2506 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
2507 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2512 std::vector<std::string > records;
2513 if(recordList ==
"*")
2516 records = startNode.getChildrenNames();
2517 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2518 for(
auto& record : records)
2519 __SUP_COUT__ <<
"recordList " << record << __E__;
2521 else if(recordList !=
"")
2525 std::istringstream f(recordList);
2526 std::string recordStr;
2527 while(getline(f, recordStr,
','))
2529 records.push_back(StringMacros::decodeURIComponent(recordStr));
2531 __SUP_COUT__ << recordList << __E__;
2532 for(
auto& record : records)
2533 __SUP_COUT__ <<
"recordList " << record << __E__;
2538 std::vector<std::string > fieldsToGet;
2543 if(fieldList ==
"AUTO")
2548 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
2550 std::vector<ConfigurationTree::RecordField> retFieldList;
2551 std::vector<std::string > fieldAcceptList,
2553 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
2554 retFieldList = startNode.getCommonFields(
2555 records, fieldAcceptList, fieldRejectList, 5,
true );
2557 for(
const auto& retField : retFieldList)
2558 fieldsToGet.push_back(retField.columnName_);
2562 std::istringstream f(fieldList);
2563 std::string fieldPath;
2564 while(getline(f, fieldPath,
','))
2566 fieldsToGet.push_back(StringMacros::decodeURIComponent(fieldPath));
2568 __SUP_COUTV__(fieldList);
2572 __SUP_COUTV__(StringMacros::vectorToString(fieldsToGet));
2575 for(
auto& field : fieldsToGet)
2577 __SUP_COUTV__(field);
2579 DOMElement* parentEl = xmlOut.addTextElementToData(
"field", field);
2582 std::set<std::string > uniqueValues;
2585 cfgMgr->getNode(startPath).getUniqueValuesForField(records, field);
2587 for(
auto& uniqueValue : uniqueValues)
2589 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
2591 xmlOut.addTextElementToParent(
"uniqueValue", uniqueValue, parentEl);
2595 catch(std::runtime_error& e)
2597 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
2599 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2600 xmlOut.addTextElementToData(
"Error", ss.str());
2604 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
2605 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2606 xmlOut.addTextElementToData(
"Error", ss.str());
2630 void ConfigurationGUISupervisor::handleFillTreeViewXML(HttpXmlDocument& xmlOut,
2631 ConfigurationManagerRW* cfgMgr,
2632 const std::string& groupName,
2633 const TableGroupKey& groupKey,
2634 const std::string& startPath,
2636 bool hideStatusFalse,
2637 const std::string& modifiedTables,
2638 const std::string& filterList)
2669 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
2670 std::map<std::string , TableVersion > memberMap;
2672 std::string accumulatedErrors =
"";
2675 setupActiveTablesXML(
2690 catch(
const std::runtime_error& e)
2692 __SS__ <<
"Error occured setting up active tables: " << e.what() << __E__;
2693 accumulatedErrors += ss.str();
2697 __SS__ <<
"Unknown error occured setting up active tables." << __E__;
2698 accumulatedErrors += ss.str();
2701 if(accumulatedErrors !=
"")
2703 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
2705 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
2709 __SUP_COUT__ <<
"Active tables are setup. No issues found." << __E__;
2713 DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
2718 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
2720 if(startPath ==
"/")
2724 std::string accumulateTreeErrs;
2726 if(usingActiveGroups)
2727 rootMap = cfgMgr->getChildren(0, &accumulateTreeErrs);
2729 rootMap = cfgMgr->getChildren(&memberMap, &accumulateTreeErrs);
2731 __SUP_COUT__ <<
"accumulateTreeErrs = " << accumulateTreeErrs << __E__;
2732 if(accumulateTreeErrs !=
"")
2733 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
2737 ConfigurationTree startNode =
2738 cfgMgr->getNode(startPath,
true );
2739 if(startNode.isLinkNode() && startNode.isDisconnected())
2741 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
2746 std::map<std::string , std::string > filterMap;
2747 StringMacros::getMapFromString(
2750 std::set<char>({
';'}) ,
2751 std::set<char>({
'='}) );
2753 __COUTV__(StringMacros::mapToString(filterMap));
2755 rootMap = cfgMgr->getNode(startPath).getChildren(filterMap);
2758 for(
auto& treePair : rootMap)
2760 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
2762 catch(std::runtime_error& e)
2764 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
2765 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2766 xmlOut.addTextElementToData(
"Error", ss.str());
2770 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
2771 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2772 xmlOut.addTextElementToData(
"Error", ss.str());
2782 void ConfigurationGUISupervisor::recursiveTreeToXML(
const ConfigurationTree& t,
2784 HttpXmlDocument& xmlOut,
2785 DOMElement* parentEl,
2786 bool hideStatusFalse)
2792 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2793 xmlOut.addTextElementToParent(
"value", t.getValueAsString(), parentEl);
2794 parentEl = xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2798 if(t.getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
2799 t.getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
2803 std::vector<std::string> choices = t.getFixedChoices();
2804 for(
const auto& choice : choices)
2805 xmlOut.addTextElementToParent(
"fixedChoice", choice, parentEl);
2816 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2818 if(t.isDisconnected())
2820 __COUT__ << t.getValueName() << __E__;
2826 xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2829 xmlOut.addTextElementToParent(
2830 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
2831 t.getDisconnectedLinkID(),
2833 xmlOut.addTextElementToParent(
2834 "LinkTableName", t.getDisconnectedTableName(), parentEl);
2835 xmlOut.addTextElementToParent(
2836 "LinkIndex", t.getChildLinkIndex(), parentEl);
2839 DOMElement* choicesParentEl =
2840 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
2844 std::vector<std::string> choices = t.getFixedChoices();
2845 __COUT__ <<
"choices.size() " << choices.size() << __E__;
2847 for(
const auto& choice : choices)
2848 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2860 xmlOut.addTextElementToParent(
2861 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
2862 t.getValueAsString(),
2865 xmlOut.addTextElementToParent(
"LinkTableName", t.getTableName(), parentEl);
2867 xmlOut.addTextElementToParent(
"LinkIndex", t.getChildLinkIndex(), parentEl);
2871 DOMElement* choicesParentEl =
2872 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
2873 std::vector<std::string> choices = t.getFixedChoices();
2877 for(
const auto& choice : choices)
2878 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2883 bool returnNode =
true;
2889 t.getNode(TableViewColumnInfo::COL_NAME_STATUS).getValue(returnNode);
2898 xmlOut.addTextElementToParent(
"node", t.getValueAsString(), parentEl);
2907 auto C = t.getChildren();
2910 c.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
2922 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
2923 HttpXmlDocument& xmlOut,
2924 ConfigurationManagerRW* cfgMgr,
2925 const std::string& linkToTableName,
2926 const TableVersion& linkToTableVersion,
2927 const std::string& linkIdType,
2928 const std::string& linkIndex,
2929 const std::string& linkInitId)
try
2941 const std::string& tableName = linkToTableName;
2942 const TableVersion& version = linkToTableVersion;
2943 TableBase* config = cfgMgr->getTableByName(tableName);
2946 config->setActiveView(version);
2950 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
2951 << version << __E__;
2952 cfgMgr->getVersionedTableByName(tableName, version);
2955 if(version != config->getViewVersion())
2957 __SUP_SS__ <<
"Target table version (" << version
2958 <<
") is not the currently active version ("
2959 << config->getViewVersion() <<
". Try refreshing the tree." << __E__;
2960 __SUP_COUT_WARN__ << ss.str();
2964 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
2966 if(linkIdType ==
"UID")
2969 unsigned int col = config->getView().getColUID();
2970 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
2971 xmlOut.addTextElementToData(
"linkToChoice",
2972 config->getView().getDataView()[row][col]);
2974 else if(linkIdType ==
"GroupID")
2980 __SUP_COUTV__(linkIndex);
2981 __SUP_COUTV__(linkInitId);
2983 std::set<std::string> setOfGroupIDs =
2984 config->getView().getSetOfGroupIDs(linkIndex);
2989 bool foundInitId =
false;
2990 for(
const auto& groupID : setOfGroupIDs)
2992 if(!foundInitId && linkInitId == groupID)
2995 xmlOut.addTextElementToData(
"linkToChoice", groupID);
2999 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
3002 unsigned int col = config->getView().getColUID();
3003 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
3005 xmlOut.addTextElementToData(
"groupChoice",
3006 config->getView().getDataView()[row][col]);
3007 if(config->getView().isEntryInGroup(row, linkIndex, linkInitId))
3008 xmlOut.addTextElementToData(
"groupMember",
3009 config->getView().getDataView()[row][col]);
3014 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
3018 catch(std::runtime_error& e)
3020 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
3021 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3022 xmlOut.addTextElementToData(
"Error", ss.str());
3026 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
3027 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3028 xmlOut.addTextElementToData(
"Error", ss.str());
3033 void ConfigurationGUISupervisor::handleMergeGroupsXML(
3034 HttpXmlDocument& xmlOut,
3035 ConfigurationManagerRW* cfgMgr,
3036 const std::string& groupANameContext,
3037 const TableGroupKey& groupAKeyContext,
3038 const std::string& groupBNameContext,
3039 const TableGroupKey& groupBKeyContext,
3040 const std::string& groupANameConfig,
3041 const TableGroupKey& groupAKeyConfig,
3042 const std::string& groupBNameConfig,
3043 const TableGroupKey& groupBKeyConfig,
3044 const std::string& author,
3045 const std::string& mergeApproach)
try
3047 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
3048 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3049 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3050 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3051 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
3067 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
3068 mergeApproach ==
"Skip"))
3070 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
3074 std::map<std::string , TableVersion > memberMapAContext,
3075 memberMapBContext, memberMapAConfig, memberMapBConfig;
3078 bool skippingContextPair =
false;
3079 bool skippingConfigPair =
false;
3080 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
3081 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
3083 skippingContextPair =
true;
3084 __SUP_COUTV__(skippingContextPair);
3086 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
3087 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
3089 skippingConfigPair =
true;
3090 __SUP_COUTV__(skippingConfigPair);
3094 if(!skippingContextPair)
3096 cfgMgr->loadTableGroup(groupANameContext,
3108 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
3110 cfgMgr->loadTableGroup(groupBNameContext,
3123 __SUP_COUTV__(StringMacros::mapToString(memberMapBContext));
3127 if(!skippingConfigPair)
3129 cfgMgr->loadTableGroup(groupANameConfig,
3141 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
3143 cfgMgr->loadTableGroup(groupBNameConfig,
3156 __SUP_COUTV__(StringMacros::mapToString(memberMapBConfig));
3164 std::map<std::pair<std::string , std::string >,
3168 std::pair<std::string ,
3169 std::pair<std::string , std::string >>,
3171 groupidConversionMap;
3175 for(
unsigned int i = 0; i < 2; ++i)
3177 if(i == 0 && mergeApproach !=
"Rename")
3181 for(
unsigned int j = 0; j < 2; ++j)
3183 if(j == 0 && skippingContextPair)
3185 __COUT__ <<
"Skipping context pair..." << __E__;
3188 else if(j == 1 && skippingConfigPair)
3190 __COUT__ <<
"Skipping config pair..." << __E__;
3194 std::map<std::string , TableVersion >& memberMapAref =
3195 j == 0 ? memberMapAContext : memberMapAConfig;
3197 std::map<std::string , TableVersion >& memberMapBref =
3198 j == 0 ? memberMapBContext : memberMapBConfig;
3201 __COUT__ <<
"Context pair..." << __E__;
3203 __COUT__ <<
"Config pair..." << __E__;
3205 __COUT__ <<
"Starting member map B scan." << __E__;
3206 for(
const auto bkey : memberMapBref)
3208 __SUP_COUTV__(bkey.first);
3210 if(memberMapAref.find(bkey.first) == memberMapAref.end())
3213 memberMapAref[bkey.first] = bkey.second;
3215 else if(memberMapAref[bkey.first] != bkey.second)
3218 __SUP_COUTV__(memberMapAref[bkey.first]);
3219 __SUP_COUTV__(bkey.second);
3222 TableBase* config = cfgMgr->getTableByName(bkey.first);
3224 __SUP_COUT__ <<
"Got table." << __E__;
3226 TableVersion newVersion = config->mergeViews(
3228 ->getVersionedTableByName(bkey.first,
3229 memberMapAref[bkey.first])
3231 cfgMgr->getVersionedTableByName(bkey.first, bkey.second)
3237 groupidConversionMap,
3240 config->getTableName() ==
3241 ConfigurationManager::
3242 XDAQ_APPLICATION_TABLE_NAME
3248 __SUP_COUTV__(newVersion);
3254 newVersion = saveModifiedVersionXML(
3265 catch(std::runtime_error& e)
3268 <<
"There was an error saving the '"
3269 << config->getTableName()
3270 <<
"' merge result to a persistent table version. "
3271 <<
"Perhaps you can modify this table in one of the "
3272 "groups to resolve this issue, and then re-merge."
3273 << __E__ << e.what();
3277 __SUP_COUTV__(newVersion);
3279 memberMapAref[bkey.first] = newVersion;
3288 if(!skippingContextPair)
3290 __SUP_COUT__ <<
"New context member map complete." << __E__;
3291 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
3294 TableGroupKey newKeyContext = cfgMgr->saveNewTableGroup(
3297 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.toString() +
3298 ") and " + groupBNameContext +
" (" + groupBKeyContext.toString() +
").");
3301 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
3302 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.toString());
3304 if(!skippingConfigPair)
3306 __SUP_COUT__ <<
"New config member map complete." << __E__;
3307 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
3310 TableGroupKey newKeyConfig = cfgMgr->saveNewTableGroup(
3313 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.toString() +
3314 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.toString() +
").");
3317 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
3318 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.toString());
3322 catch(std::runtime_error& e)
3324 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
3325 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3326 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3327 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3328 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
3329 << e.what() << __E__;
3330 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3331 xmlOut.addTextElementToData(
"Error", ss.str());
3335 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
3336 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3337 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3338 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3339 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
3340 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3341 xmlOut.addTextElementToData(
"Error", ss.str());
3346 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
3347 HttpXmlDocument& xmlOut,
3348 ConfigurationManagerRW* cfgMgr,
3349 const std::string& groupName,
3350 const TableGroupKey& groupKey,
3351 const std::string& modifiedTables,
3352 const std::string& author,
3353 const std::string& planName,
3354 const std::string& commandString)
try
3356 __MOUT__ <<
"handleSavePlanCommandSequenceXML" << __E__;
3359 setupActiveTablesXML(xmlOut,
3369 TableEditStruct planTable(IterateTable::PLAN_TABLE,
3371 TableEditStruct targetTable(IterateTable::TARGET_TABLE,
3375 std::map<std::string, TableEditStruct> commandTypeToCommandTableMap;
3376 for(
const auto& commandPair : IterateTable::commandToTableMap_)
3377 if(commandPair.second !=
"")
3378 commandTypeToCommandTableMap.emplace(std::pair<std::string, TableEditStruct>(
3379 commandPair.first, TableEditStruct(commandPair.second, cfgMgr)));
3395 std::string groupName = planName +
"-Plan";
3396 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
3398 unsigned int groupIdCol =
3399 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
3400 unsigned int cmdTypeCol =
3401 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
3403 unsigned int targetGroupIdCol =
3404 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
3405 unsigned int targetTableCol =
3406 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
3407 unsigned int targetUIDCol =
3408 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
3410 std::string groupLinkIndex =
3411 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
3412 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
3414 std::pair<
unsigned int ,
unsigned int > commandUidLink;
3417 planTable.tableView_->getChildLink(
3418 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
3423 unsigned int cmdRow, cmdCol;
3424 std::string targetGroupName;
3428 std::string targetUID, cmdType;
3430 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
3433 targetUID = planTable.tableView_
3434 ->getDataView()[row][planTable.tableView_->getColUID()];
3435 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
3438 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
3440 __SUP_COUT__ <<
"Removing." << __E__;
3444 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
3445 if(commandTypeToCommandTableMap.find(cmdType) !=
3446 commandTypeToCommandTableMap
3450 commandTypeToCommandTableMap[cmdType].tableView_->findRow(
3451 commandTypeToCommandTableMap[cmdType]
3452 .tableView_->getColUID(),
3453 planTable.tableView_
3454 ->getDataView()[row][commandUidLink.second]);
3462 commandTypeToCommandTableMap[cmdType].tableView_->findCol(
3463 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
3465 commandTypeToCommandTableMap[cmdType]
3466 .tableView_->getDataView()[cmdRow][cmdCol];
3468 for(
unsigned int trow = 0;
3469 trow < targetTable.tableView_->getNumberOfRows();
3473 if(targetTable.tableView_->isEntryInGroup(
3475 commandTypeToCommandTableMap[cmdType]
3476 .tableView_->getColumnInfo(cmdCol)
3477 .getChildLinkIndex(),
3480 __SUP_COUT__ <<
"Removing target." << __E__;
3482 if(targetTable.tableView_->removeRowFromGroup(
3493 __SUP_COUT__ <<
"No targets." << __E__;
3498 commandTypeToCommandTableMap[cmdType].tableView_->deleteRow(
3501 commandTypeToCommandTableMap[cmdType].modified_ =
true;
3505 if(planTable.tableView_->removeRowFromGroup(
3506 row, groupIdCol, groupName,
true ))
3515 std::vector<IterateTable::Command> commands;
3520 std::istringstream f(commandString);
3521 std::string commandSubString, paramSubString, paramValue;
3523 while(getline(f, commandSubString,
';'))
3526 std::istringstream g(commandSubString);
3529 while(getline(g, paramSubString,
','))
3534 if(paramSubString !=
"type")
3536 __SUP_SS__ <<
"Invalid command sequence" << __E__;
3540 commands.push_back(IterateTable::Command());
3542 getline(g, paramValue,
',');
3545 commands.back().type_ = paramValue;
3549 getline(g, paramValue,
',');
3553 commands.back().params_.emplace(
3554 std::pair<std::string ,
3557 StringMacros::decodeURIComponent(paramValue)));
3566 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
3573 unsigned int row, tgtRow;
3574 unsigned int targetIndex;
3575 std::string targetStr, cmdUID;
3577 for(
auto& command : commands)
3579 __SUP_COUT__ <<
"command " << command.type_ << __E__;
3580 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
3584 row = planTable.tableView_->addRow(author,
"planCommand");
3585 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
3588 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
3591 planTable.tableView_->setValueAsString(
3592 "1", row, planTable.tableView_->getColStatus());
3595 if(commandTypeToCommandTableMap.find(command.type_) !=
3596 commandTypeToCommandTableMap.end())
3599 __SUP_COUT__ <<
"table "
3600 << commandTypeToCommandTableMap[command.type_].tableName_
3606 cmdRow = commandTypeToCommandTableMap[command.type_].tableView_->addRow(
3607 author,
true , command.type_ +
"_COMMAND_");
3613 for(
auto& param : command.params_)
3615 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
3618 if(param.first == IterateTable::targetParams_.Tables_)
3620 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
3621 std::istringstream f(param.second);
3624 while(getline(f, targetStr,
'='))
3626 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3627 if(!command.targets_.size() ||
3628 command.targets_.back().table_ !=
"")
3630 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
3633 command.addTarget();
3634 command.targets_.back().table_ = targetStr;
3637 command.targets_[targetIndex++].table_ = targetStr;
3643 if(param.first == IterateTable::targetParams_.UIDs_)
3645 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
3646 std::istringstream f(param.second);
3649 while(getline(f, targetStr,
'='))
3651 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3652 if(!command.targets_.size() ||
3653 command.targets_.back().UID_ !=
"")
3655 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
3658 command.addTarget();
3659 command.targets_.back().UID_ = targetStr;
3662 command.targets_[targetIndex++].UID_ = targetStr;
3668 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3671 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
3673 commandTypeToCommandTableMap[command.type_]
3674 .tableView_->setURIEncodedValue(param.second, cmdRow, cmdCol);
3678 commandTypeToCommandTableMap[command.type_].tableView_->getDataView()
3679 [cmdRow][commandTypeToCommandTableMap[command.type_]
3680 .tableView_->getColUID()];
3682 if(command.targets_.size())
3686 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
3690 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3691 IterateTable::commandTargetCols_.TargetsLink_);
3692 commandTypeToCommandTableMap[command.type_]
3693 .tableView_->setValueAsString(
3694 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
3697 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3698 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
3699 commandTypeToCommandTableMap[command.type_]
3700 .tableView_->setValueAsString(
3701 cmdUID +
"_Targets", cmdRow, cmdCol);
3705 for(
const auto& target : command.targets_)
3707 __SUP_COUT__ << target.table_ <<
" " << target.UID_ << __E__;
3710 tgtRow = targetTable.tableView_->addRow(author,
"commandTarget");
3711 targetTable.tableView_->addRowToGroup(
3712 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
3715 targetTable.tableView_->setValueAsString(
3716 target.table_, tgtRow, targetTableCol);
3719 targetTable.tableView_->setValueAsString(
3720 target.UID_, tgtRow, targetUIDCol);
3725 planTable.tableView_->setValueAsString(
3726 commandTypeToCommandTableMap[command.type_].tableName_,
3728 commandUidLink.first);
3729 planTable.tableView_->setValueAsString(
3730 cmdUID, row, commandUidLink.second);
3732 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
3734 commandTypeToCommandTableMap[command.type_].modified_ =
true;
3742 planTable.tableView_->print();
3743 planTable.tableView_->init();
3745 __SUP_COUT__ <<
"requestType tables:" << __E__;
3747 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3749 modifiedConfig.second.tableView_->print();
3750 modifiedConfig.second.tableView_->init();
3753 targetTable.tableView_->print();
3754 targetTable.tableView_->init();
3759 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
3765 if(planTable.createdTemporaryVersion_)
3767 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
3768 << planTable.temporaryVersion_ << __E__;
3770 cfgMgr->eraseTemporaryVersion(planTable.tableName_,
3771 planTable.temporaryVersion_);
3774 if(targetTable.createdTemporaryVersion_)
3776 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
3777 << targetTable.temporaryVersion_ << __E__;
3779 cfgMgr->eraseTemporaryVersion(targetTable.tableName_,
3780 targetTable.temporaryVersion_);
3783 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3785 if(modifiedConfig.second
3786 .createdTemporaryVersion_)
3788 __SUP_COUT__ <<
"Erasing temporary version "
3789 << modifiedConfig.second.tableName_ <<
"-v"
3790 << modifiedConfig.second.temporaryVersion_ << __E__;
3792 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
3793 modifiedConfig.second.temporaryVersion_);
3804 TableVersion finalVersion = saveModifiedVersionXML(
3807 planTable.tableName_,
3808 planTable.originalVersion_,
3811 planTable.temporaryVersion_,
3814 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
3815 << finalVersion << __E__;
3817 finalVersion = saveModifiedVersionXML(
3820 targetTable.tableName_,
3821 targetTable.originalVersion_,
3824 targetTable.temporaryVersion_,
3827 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
3828 << finalVersion << __E__;
3830 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3832 if(!modifiedConfig.second.modified_)
3834 if(modifiedConfig.second
3835 .createdTemporaryVersion_)
3837 __SUP_COUT__ <<
"Erasing unmodified temporary version "
3838 << modifiedConfig.second.tableName_ <<
"-v"
3839 << modifiedConfig.second.temporaryVersion_ << __E__;
3841 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
3842 modifiedConfig.second.temporaryVersion_);
3847 finalVersion = saveModifiedVersionXML(
3850 modifiedConfig.second.tableName_,
3851 modifiedConfig.second.originalVersion_,
3853 modifiedConfig.second.table_,
3854 modifiedConfig.second.temporaryVersion_,
3857 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
3858 << finalVersion << __E__;
3861 handleFillModifiedTablesXML(xmlOut, cfgMgr);
3863 catch(std::runtime_error& e)
3865 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
3866 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3867 xmlOut.addTextElementToData(
"Error", ss.str());
3871 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
3872 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3873 xmlOut.addTextElementToData(
"Error", ss.str());
3886 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(HttpXmlDocument& xmlOut,
3887 ConfigurationManagerRW* cfgMgr,
3888 const std::string& tableName,
3889 TableVersion version,
3890 const std::string& type,
3891 const std::string& uid,
3892 const std::string& colName,
3893 const std::string& newValue,
3894 const std::string& author)
try
3896 __SUP_COUT__ <<
"table " << tableName <<
"(" << version <<
")" << __E__;
3903 TableBase* config = cfgMgr->getTableByName(tableName);
3906 config->setActiveView(version);
3910 if(version.isTemporaryVersion())
3913 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
3914 << version << __E__;
3915 cfgMgr->getVersionedTableByName(tableName, version);
3918 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
3920 if(version != config->getViewVersion())
3922 __SUP_SS__ <<
"Target table version (" << version
3923 <<
") is not the currently active version ("
3924 << config->getViewVersion() <<
". Try refreshing the tree." << __E__;
3928 unsigned int col = -1;
3929 if(type ==
"uid" || type ==
"delete-uid")
3930 col = config->getView().getColUID();
3931 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
3932 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
3933 col = config->getView().findCol(colName);
3934 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
3935 type ==
"table-newUIDRow" || type ==
"table-newRow")
3939 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
3944 if(type ==
"table" || type ==
"link-comment")
3947 if(config->getView().isURIEncodedCommentTheSame(newValue))
3949 __SUP_SS__ <<
"Comment '" << newValue
3950 <<
"' is the same as the current comment. No need to save change."
3966 TableVersion temporaryVersion = config->createTemporaryView(version);
3968 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
3970 TableView* cfgView = config->getTemporaryView(temporaryVersion);
3976 if(type ==
"table" || type ==
"link-comment")
3979 cfgView->setURIEncodedComment(newValue);
3981 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
3984 unsigned int row = cfgView->addRow(author,
true );
3989 col = cfgView->getColStatus();
3990 cfgView->setValueAsString(
"1", row, col);
3997 cfgView->setURIEncodedValue(newValue, row, cfgView->getColUID());
3999 else if(type ==
"table-newGroupRow")
4002 unsigned int row = cfgView->addRow(author,
true );
4005 unsigned int csvIndex = newValue.find(
',');
4007 std::string linkIndex = newValue.substr(0, csvIndex);
4008 std::string groupId = newValue.substr(csvIndex + 1);
4011 csvIndex = groupId.find(
',');
4012 std::string newRowUID = groupId.substr(csvIndex + 1);
4013 groupId = groupId.substr(0, csvIndex);
4015 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
4019 cfgView->setURIEncodedValue(newRowUID, row, cfgView->getColUID());
4022 col = cfgView->getColLinkGroupID(linkIndex);
4025 cfgView->setURIEncodedValue(groupId, row, col);
4030 col = cfgView->getColStatus();
4031 cfgView->setValueAsString(
"1", row, col);
4037 else if(type ==
"delete-uid")
4040 unsigned int row = cfgView->findRow(col, uid);
4041 cfgView->deleteRow(row);
4043 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
4044 type ==
"value-bool" || type ==
"value-bitmap")
4046 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
4047 if(!cfgView->setURIEncodedValue(newValue, row, col, author))
4050 __SUP_SS__ <<
"Value '" << newValue
4051 <<
"' is the same as the current value. No need to save "
4052 "change to tree node."
4057 else if(type ==
"link-UID" || type ==
"link-GroupID")
4060 std::pair<
unsigned int ,
unsigned int > linkPair;
4061 if(!cfgView->getChildLink(col, isGroup, linkPair))
4064 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
4068 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
4071 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
4073 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
4076 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
4078 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
4079 csvIndexStart = csvIndex + 1;
4080 csvIndex = newValue.find(
',', csvIndexStart);
4081 std::string newLinkId = newValue.substr(
4086 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
4089 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
4090 bool changed =
false;
4091 if(!cfgView->setURIEncodedValue(newTable, row, linkPair.first, author))
4094 __SUP_COUT__ <<
"Value '" << newTable
4095 <<
"' is the same as the current value." << __E__;
4100 if(!cfgView->setURIEncodedValue(newLinkId, row, linkPair.second, author))
4103 __SUP_COUT__ <<
"Value '" << newLinkId
4104 <<
"' is the same as the current value." << __E__;
4112 if(type ==
"link-GroupID")
4114 bool secondaryChanged =
false;
4119 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
4121 config->eraseView(temporaryVersion);
4129 saveModifiedVersionXML(xmlOut,
4141 catch(std::runtime_error&
4144 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
4145 "temporary version."
4147 config->eraseView(temporaryVersion);
4151 xmlOut.addTextElementToData(
4153 "Error saving primary tree node! " + std::string(e.what()));
4163 csvIndexStart = csvIndex + 1;
4164 csvIndex = newValue.find(
',', csvIndexStart);
4165 version = TableVersion(newValue.substr(
4166 csvIndexStart, csvIndex - csvIndexStart));
4169 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
4177 config = cfgMgr->getTableByName(newTable);
4180 config->setActiveView(version);
4184 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
4186 << version << __E__;
4187 cfgMgr->getVersionedTableByName(newTable, version);
4190 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
4192 if(version != config->getViewVersion())
4194 __SUP_SS__ <<
"Target table version (" << version
4195 <<
") is not the currently active version ("
4196 << config->getViewVersion() <<
". Try refreshing the tree."
4202 temporaryVersion = config->createTemporaryView(version);
4204 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
4206 cfgView = config->getTemporaryView(temporaryVersion);
4208 col = cfgView->getColLinkGroupID(linkIndex);
4210 __SUP_COUT__ <<
"target col " << col << __E__;
4213 std::vector<std::string> memberUIDs;
4216 csvIndexStart = csvIndex + 1;
4217 csvIndex = newValue.find(
',', csvIndexStart);
4218 memberUIDs.push_back(
4219 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
4220 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
4221 }
while(csvIndex != (
unsigned int)std::string::npos);
4231 std::string targetUID;
4232 bool shouldBeInGroup;
4233 bool defaultIsInGroup =
4237 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
4239 targetUID = cfgView->getDataView()[row][cfgView->getColUID()];
4240 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4242 shouldBeInGroup =
false;
4243 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
4244 if(targetUID == memberUIDs[i])
4247 shouldBeInGroup =
true;
4251 isInGroup = cfgView->isEntryInGroup(row, linkIndex, newLinkId);
4254 if(shouldBeInGroup && !isInGroup)
4256 __SUP_COUT__ <<
"Changed YES: " << row << __E__;
4257 secondaryChanged =
true;
4259 cfgView->addRowToGroup(row, col, newLinkId);
4262 else if(!shouldBeInGroup && isInGroup)
4264 __SUP_COUT__ <<
"Changed NO: " << row << __E__;
4265 secondaryChanged =
true;
4267 cfgView->removeRowFromGroup(row, col, newLinkId);
4269 else if(targetUID ==
4270 cfgView->getDefaultRowValues()[cfgView->getColUID()] &&
4274 defaultIsInGroup =
true;
4279 if(!secondaryChanged)
4282 <<
"No changes to secondary view. Erasing temporary table."
4284 config->eraseView(temporaryVersion);
4292 saveModifiedVersionXML(xmlOut,
4304 catch(std::runtime_error&
4307 __SUP_COUT__ <<
"Caught error while editing secondary table. "
4308 "Erasing temporary version."
4310 config->eraseView(temporaryVersion);
4311 secondaryChanged =
false;
4314 xmlOut.addTextElementToData(
4316 "Error saving secondary tree node! " + std::string(e.what()));
4324 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
4326 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
4328 <<
"', and selected group members are the same as the "
4330 <<
"No need to save changes to tree." << __E__;
4336 else if(0 && !changed)
4341 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
4343 <<
"' are the same as the current values. No need to save "
4344 "change to tree node."
4354 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
4355 config->eraseView(temporaryVersion);
4359 saveModifiedVersionXML(xmlOut,
4368 catch(std::runtime_error& e)
4370 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
4371 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4372 xmlOut.addTextElementToData(
"Error", ss.str());
4376 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
4377 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4378 xmlOut.addTextElementToData(
"Error", ss.str());
4404 void ConfigurationGUISupervisor::handleGetTableGroupXML(HttpXmlDocument& xmlOut,
4405 ConfigurationManagerRW* cfgMgr,
4406 const std::string& groupName,
4407 TableGroupKey groupKey,
4408 bool ignoreWarnings)
try
4410 char tmpIntStr[100];
4411 DOMElement *parentEl, *configEl;
4434 const GroupInfo& groupInfo = cfgMgr->getGroupInfo(groupName);
4435 const std::set<TableGroupKey>& sortedKeys = groupInfo.keys_;
4437 if(groupKey.isInvalid() ||
4438 sortedKeys.find(groupKey) == sortedKeys.end())
4440 if(sortedKeys.size())
4441 groupKey = *sortedKeys.rbegin();
4442 __SUP_COUT__ <<
"Group key requested was invalid or not found, going with latest "
4443 << groupKey << __E__;
4446 xmlOut.addTextElementToData(
"TableGroupName", groupName);
4447 xmlOut.addTextElementToData(
"TableGroupKey", groupKey.toString());
4450 for(
auto& keyInOrder : sortedKeys)
4451 xmlOut.addTextElementToData(
"HistoricalTableGroupKey", keyInOrder.toString());
4453 parentEl = xmlOut.addTextElementToData(
"TableGroupMembers",
"");
4456 std::map<std::string , TableVersion > memberMap;
4457 std::map<std::string , std::string > groupMemberAliases;
4459 __SUP_COUT__ <<
"groupName=" << groupName << __E__;
4460 __SUP_COUT__ <<
"groupKey=" << groupKey << __E__;
4462 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
4463 std::map<std::string, TableInfo>::const_iterator it;
4469 std::string groupAuthor, groupComment, groupCreationTime, groupTypeString;
4470 std::string accumulateTreeErrors;
4472 __SUP_COUTV__(ignoreWarnings);
4473 cfgMgr->loadTableGroup(groupName,
4478 ignoreWarnings ? 0 :
4479 &accumulateTreeErrors,
4485 &groupMemberAliases);
4487 if(accumulateTreeErrors !=
"")
4489 __SUP_COUTV__(accumulateTreeErrors);
4490 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrors);
4493 xmlOut.addTextElementToData(
"TableGroupAuthor", groupAuthor);
4494 xmlOut.addTextElementToData(
"TableGroupComment", groupComment);
4495 xmlOut.addTextElementToData(
"TableGroupCreationTime", groupCreationTime);
4496 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
4498 catch(
const std::runtime_error& e)
4500 __SUP_SS__ <<
"Table group \"" + groupName +
"(" + groupKey.toString() +
")" +
4501 "\" members can not be loaded!\n\n" + e.what()
4503 __SUP_COUT_ERR__ << ss.str();
4504 xmlOut.addTextElementToData(
"Error", ss.str());
4509 __SUP_SS__ <<
"Table group \"" + groupName +
"(" + groupKey.toString() +
")" +
4510 "\" members can not be loaded!"
4512 __SUP_COUT_ERR__ << ss.str();
4513 xmlOut.addTextElementToData(
"Error", ss.str());
4517 __COUTV__(StringMacros::mapToString(groupMemberAliases));
4519 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
4520 cfgMgr->getVersionAliases();
4522 __SUP_COUT__ <<
"# of table version aliases: " << versionAliases.size() << __E__;
4525 for(
auto& memberPair : memberMap)
4527 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
4530 if(groupMemberAliases.find(memberPair.first) != groupMemberAliases.end())
4531 configEl = xmlOut.addTextElementToParent(
4533 ConfigurationManager::ALIAS_VERSION_PREAMBLE +
4534 groupMemberAliases[memberPair.first],
4537 configEl = xmlOut.addTextElementToParent(
4538 "MemberVersion", memberPair.second.toString(), parentEl);
4540 it = allTableInfo.find(memberPair.first);
4541 if(it == allTableInfo.end())
4543 xmlOut.addTextElementToData(
4544 "Error",
"Table \"" + memberPair.first +
"\" can not be retrieved!");
4548 if(versionAliases.find(it->first) != versionAliases.end())
4549 for(
auto& aliasVersion : versionAliases[it->first])
4550 xmlOut.addTextElementToParent(
4551 "TableExistingVersion",
4552 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
4555 for(
auto& version : it->second.versions_)
4558 xmlOut.addTextElementToParent(
4559 "TableExistingVersion", version.toString(), configEl);
4562 for(
auto& memberPair : memberMap)
4569 xmlOut.addTextElementToParent(
4571 allTableInfo.at(memberPair.first).tablePtr_->getView().getComment(),
4608 catch(std::runtime_error& e)
4610 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
4611 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4612 xmlOut.addTextElementToData(
"Error", ss.str());
4616 __SUP_SS__ << (
"Error!\n\n") << __E__;
4617 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4618 xmlOut.addTextElementToData(
"Error", ss.str());
4662 void ConfigurationGUISupervisor::handleGetTableXML(HttpXmlDocument& xmlOut,
4663 ConfigurationManagerRW* cfgMgr,
4664 const std::string& tableName,
4665 TableVersion version,
4666 bool allowIllegalColumns)
try
4668 char tmpIntStr[100];
4669 DOMElement *parentEl, *subparentEl;
4671 std::string accumulatedErrors =
"";
4673 const std::map<std::string, TableInfo>&
4675 cfgMgr->getAllTableInfo(allowIllegalColumns,
4676 allowIllegalColumns ? &accumulatedErrors : 0,
4679 TableBase* table = cfgMgr->getTableByName(tableName);
4683 xmlOut.addTextElementToData(
"ExistingTableNames",
4684 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
4685 for(
auto& configPair : allTableInfo)
4687 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
4688 if(configPair.first == tableName &&
4689 configPair.second.versions_.find(version) == configPair.second.versions_.end())
4691 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
4692 version = TableVersion();
4696 xmlOut.addTextElementToData(
"TableName", tableName);
4697 xmlOut.addTextElementToData(
"TableDescription",
4698 table->getTableDescription());
4705 std::map<std::string , TableVersion >>
4710 versionAliases = cfgMgr->getVersionAliases();
4711 for(
const auto& aliases : versionAliases)
4712 for(
const auto& alias : aliases.second)
4713 __SUP_COUT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
4714 <<
" ==> " << alias.second << __E__;
4716 catch(
const std::runtime_error& e)
4718 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
4719 << e.what() << __E__;
4722 auto tableIterator = versionAliases.find(tableName);
4724 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
4725 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
4728 xmlOut.addTextElementToParent(
"Version", v.toString(), parentEl);
4730 if(tableIterator != versionAliases.end())
4733 for(
const auto& aliasPair : tableIterator->second)
4741 if(v == aliasPair.second)
4743 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
4744 << aliasPair.first << __E__;
4745 xmlOut.addTextElementToParent(
4746 "VersionAlias", aliasPair.first, subparentEl);
4756 TableView* cfgViewPtr;
4757 if(version.isInvalid())
4759 cfgViewPtr = table->getMockupViewP();
4765 cfgViewPtr = cfgMgr->getVersionedTableByName(tableName, version)->getViewP();
4767 catch(std::runtime_error& e)
4769 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
4770 <<
"... defaulting to mock-up! " << __E__;
4771 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
4773 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4774 version = TableVersion();
4775 cfgViewPtr = table->getMockupViewP();
4777 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4781 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
4782 <<
"... defaulting to mock-up! "
4783 <<
"(You may want to try again to see what was partially loaded "
4784 "into cache before failure. "
4785 <<
"If you think, the failure is due to a column name change, "
4786 <<
"you can also try to Copy the failing view to the new column "
4788 <<
"'Copy and Move' functionality.)" << __E__;
4790 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4791 version = TableVersion();
4792 cfgViewPtr = table->getMockupViewP();
4794 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4797 xmlOut.addTextElementToData(
"TableVersion", version.toString());
4800 DOMElement* choicesParentEl;
4801 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
4803 std::vector<TableViewColumnInfo> colInfo = cfgViewPtr->getColumnsInfo();
4805 for(
int i = 0; i < (int)colInfo.size(); ++i)
4813 xmlOut.addTextElementToParent(
"ColumnHeader", colInfo[i].getName(), parentEl);
4814 xmlOut.addTextElementToParent(
"ColumnType", colInfo[i].getType(), parentEl);
4815 xmlOut.addTextElementToParent(
4816 "ColumnDataType", colInfo[i].getDataType(), parentEl);
4818 choicesParentEl = xmlOut.addTextElementToParent(
"ColumnChoices",
"", parentEl);
4820 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
4821 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
4822 colInfo[i].isChildLink())
4824 for(
auto& choice : colInfo[i].getDataChoices())
4825 xmlOut.addTextElementToParent(
"ColumnChoice", choice, choicesParentEl);
4832 if(version.isInvalid())
4835 catch(std::runtime_error& e)
4838 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
4845 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
4847 for(
int r = 0; r < (int)cfgViewPtr->getNumberOfRows(); ++r)
4851 sprintf(tmpIntStr,
"%d", r);
4852 DOMElement* tmpParentEl =
4853 xmlOut.addTextElementToParent(
"Row", tmpIntStr, parentEl);
4855 for(
int c = 0; c < (int)cfgViewPtr->getNumberOfColumns(); ++c)
4857 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
4859 std::string timeAsString;
4860 cfgViewPtr->getValue(timeAsString, r, c);
4861 xmlOut.addTextElementToParent(
"Entry", timeAsString, tmpParentEl);
4864 xmlOut.addTextElementToParent(
4865 "Entry", cfgViewPtr->getDataView()[r][c], tmpParentEl);
4870 xmlOut.addTextElementToData(
"TableComment", cfgViewPtr->getComment());
4871 xmlOut.addTextElementToData(
"TableAuthor", cfgViewPtr->getAuthor());
4872 xmlOut.addTextElementToData(
"TableCreationTime",
4873 std::to_string(cfgViewPtr->getCreationTime()));
4874 xmlOut.addTextElementToData(
"TableLastAccessTime",
4875 std::to_string(cfgViewPtr->getLastAccessTime()));
4878 std::vector<std::string> defaultRowValues = cfgViewPtr->getDefaultRowValues();
4880 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
4885 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
4888 if(accumulatedErrors !=
"")
4890 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
4891 "maybe you can ignore this, ") +
4892 "but please note the following errors:\n" + accumulatedErrors)
4894 __SUP_COUT_ERR__ << ss.str();
4895 xmlOut.addTextElementToData(
"Error", ss.str());
4897 else if(!version.isTemporaryVersion() &&
4899 (cfgViewPtr->getDataColumnSize() != cfgViewPtr->getNumberOfColumns() ||
4900 cfgViewPtr->getSourceColumnMismatch() !=
4903 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
4904 <<
":v" << version <<
". Please see the details below:\n\n"
4905 <<
"The source column size was found to be "
4906 << cfgViewPtr->getDataColumnSize()
4907 <<
", and the current number of columns for this table is "
4908 << cfgViewPtr->getNumberOfColumns() <<
". This resulted in a count of "
4909 << cfgViewPtr->getSourceColumnMismatch()
4910 <<
" source column mismatches, and a count of "
4911 << cfgViewPtr->getSourceColumnMissing() <<
" table entries missing in "
4912 << cfgViewPtr->getNumberOfRows() <<
" row(s) of data." << __E__;
4914 const std::set<std::string> srcColNames = cfgViewPtr->getSourceColumnNames();
4915 ss <<
"\n\nSource column names in ALPHABETICAL order were as follows:\n";
4917 std::string preIndexStr =
"";
4918 for(
auto& srcColName : srcColNames)
4920 ss <<
"\n\t" << preIndexStr << index <<
". " << srcColName;
4931 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
4932 ss <<
"\n\nCurrent table column names in ALPHABETICAL order are as follows:\n";
4935 for(
auto& destColName : destColNames)
4937 ss <<
"\n\t" << preIndexStr << index <<
". " << destColName;
4948 __SUP_COUT__ <<
"\n" << ss.str();
4949 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
4952 catch(std::runtime_error& e)
4954 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
4955 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + std::string(e.what()));
4959 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
4960 xmlOut.addTextElementToData(
"Error",
"Error getting view! ");
4968 TableVersion ConfigurationGUISupervisor::saveModifiedVersionXML(
4969 HttpXmlDocument& xmlOut,
4970 ConfigurationManagerRW* cfgMgr,
4971 const std::string& tableName,
4972 TableVersion originalVersion,
4975 TableVersion temporaryModifiedVersion,
4976 bool ignoreDuplicates,
4977 bool lookForEquivalent)
4979 bool needToEraseTemporarySource =
4980 (originalVersion.isTemporaryVersion() && !makeTemporary);
4983 if(!ignoreDuplicates)
4985 __SUP_COUT__ <<
"Checking for duplicate tables..." << __E__;
4987 TableVersion duplicateVersion;
4994 const std::map<std::string, TableInfo>& allTableInfo =
4995 cfgMgr->getAllTableInfo();
4997 auto versionReverseIterator =
4998 allTableInfo.at(tableName).versions_.rbegin();
4999 __SUP_COUT__ <<
"Filling up cached from " << config->getNumberOfStoredViews()
5000 <<
" to max count of " << config->MAX_VIEWS_IN_CACHE << __E__;
5001 for(; config->getNumberOfStoredViews() < config->MAX_VIEWS_IN_CACHE &&
5002 versionReverseIterator != allTableInfo.at(tableName).versions_.rend();
5003 ++versionReverseIterator)
5005 __SUP_COUT__ <<
"Versions in reverse order " << *versionReverseIterator
5009 cfgMgr->getVersionedTableByName(
5010 tableName, *versionReverseIterator);
5012 catch(
const std::runtime_error& e)
5015 <<
"Error loadiing historical version, but ignoring: " << e.what()
5021 __SUP_COUT__ <<
"Checking duplicate..." << __E__;
5023 duplicateVersion = config->checkForDuplicate(
5024 temporaryModifiedVersion,
5025 (!originalVersion.isTemporaryVersion() && !makeTemporary)
5031 if(lookForEquivalent && !duplicateVersion.isInvalid())
5034 __SUP_COUT__ <<
"Equivalent table found in version v" << duplicateVersion
5038 if(duplicateVersion.isTemporaryVersion() && !makeTemporary)
5040 __SUP_COUT__ <<
"Need persistent. Duplicate version was temporary. "
5041 "Abandoning duplicate."
5043 duplicateVersion = TableVersion();
5050 cfgMgr->eraseTemporaryVersion(tableName, temporaryModifiedVersion);
5053 if(needToEraseTemporarySource)
5054 cfgMgr->eraseTemporaryVersion(tableName, originalVersion);
5056 xmlOut.addTextElementToData(
"savedName", tableName);
5057 xmlOut.addTextElementToData(
"savedVersion", duplicateVersion.toString());
5058 xmlOut.addTextElementToData(
"foundEquivalentVersion",
"1");
5060 __SUP_COUT__ <<
"\t\t equivalent AssignedVersion: " << duplicateVersion
5063 return duplicateVersion;
5067 if(!duplicateVersion.isInvalid())
5069 __SUP_SS__ <<
"This version of table '" << tableName
5070 <<
"' is identical to another version currently cached v"
5071 << duplicateVersion <<
". No reason to save a duplicate." << __E__;
5072 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5075 config->eraseView(temporaryModifiedVersion);
5079 __SUP_COUT__ <<
"Check for duplicate tables complete." << __E__;
5083 __SUP_COUT__ <<
"\t\t**************************** Save as temporary table version"
5086 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
5089 TableVersion newAssignedVersion =
5090 cfgMgr->saveNewTable(tableName, temporaryModifiedVersion, makeTemporary);
5092 if(needToEraseTemporarySource)
5093 cfgMgr->eraseTemporaryVersion(tableName, originalVersion);
5095 xmlOut.addTextElementToData(
"savedName", tableName);
5096 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
5098 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
5099 return newAssignedVersion;
5110 void ConfigurationGUISupervisor::handleCreateTableXML(HttpXmlDocument& xmlOut,
5111 ConfigurationManagerRW* cfgMgr,
5112 const std::string& tableName,
5113 TableVersion version,
5115 const std::string& data,
5116 const int& dataOffset,
5117 const std::string& author,
5118 const std::string& comment,
5119 bool sourceTableAsIs,
5120 bool lookForEquivalent)
try
5129 if(!version.isInvalid())
5134 cfgMgr->getVersionedTableByName(tableName, version);
5139 version = TableVersion();
5143 TableBase* config = cfgMgr->getTableByName(tableName);
5147 if(!version.isInvalid())
5151 if(config->getViewP()->getDataColumnSize() !=
5152 config->getMockupViewP()->getNumberOfColumns() ||
5153 config->getViewP()->getSourceColumnMismatch() != 0)
5155 __SUP_COUT__ <<
"config->getViewP()->getNumberOfColumns() "
5156 << config->getViewP()->getNumberOfColumns() << __E__;
5157 __SUP_COUT__ <<
"config->getMockupViewP()->getNumberOfColumns() "
5158 << config->getMockupViewP()->getNumberOfColumns() << __E__;
5159 __SUP_COUT__ <<
"config->getViewP()->getSourceColumnMismatch() "
5160 << config->getViewP()->getSourceColumnMismatch() << __E__;
5162 <<
"Source view v" << version
5163 <<
" has a mismatch in the number of columns, so using mockup as source."
5165 version = TableVersion();
5170 TableVersion temporaryVersion = config->createTemporaryView(version);
5172 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << __E__;
5174 TableView* cfgView = config->getTemporaryView(temporaryVersion);
5180 retVal = sourceTableAsIs ? 0 : cfgView->fillFromCSV(data, dataOffset, author);
5184 __SUP_COUT__ <<
"Data was the same, but columns have changed!" << __E__;
5185 __SUP_COUTV__(sourceTableAsIs);
5186 lookForEquivalent =
false;
5189 cfgView->setURIEncodedComment(comment);
5190 __SUP_COUT__ <<
"Table comment was set to:\n\t" << cfgView->getComment() << __E__;
5194 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5195 config->eraseView(temporaryVersion);
5205 if(retVal < 0 && (!version.isTemporaryVersion() || makeTemporary) &&
5206 ConfigurationInterface::isVersionTrackingEnabled())
5208 if(!version.isInvalid() &&
5210 !version.isScratchVersion())
5214 <<
"No rows were modified! No reason to fill a view with same content."
5216 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5218 config->eraseView(temporaryVersion);
5221 else if(version.isInvalid())
5222 __SUP_COUT__ <<
"This was interpreted as an attempt to create a blank table."
5224 else if(version.isScratchVersion())
5225 __SUP_COUT__ <<
"This was interpreted as an attempt to make a persistent "
5226 "version of the scratch table."
5231 __THROW__(ss.str() +
"impossible!");
5234 else if(retVal < 0 && (version.isTemporaryVersion() && !makeTemporary))
5236 __SUP_COUT__ <<
"Allowing the static data because this is converting from "
5237 "temporary to persistent version."
5240 else if(retVal < 0 && !ConfigurationInterface::isVersionTrackingEnabled())
5242 __SUP_COUT__ <<
"Allowing the static data because version tracking is OFF."
5247 __SUP_SS__ <<
"This should not be possible! Fatal error." << __E__;
5249 config->eraseView(temporaryVersion);
5254 saveModifiedVersionXML(xmlOut,
5262 lookForEquivalent || sourceTableAsIs );
5264 catch(std::runtime_error& e)
5266 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
5267 xmlOut.addTextElementToData(
"Error",
5268 "Error saving new view!\n " + std::string(e.what()));
5272 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
5273 xmlOut.addTextElementToData(
"Error",
"Error saving new view! ");
5287 ConfigurationManagerRW* ConfigurationGUISupervisor::refreshUserSession(
5288 std::string username, uint64_t activeSessionIndex,
bool refresh)
5291 activeSessionIndex =
5294 std::stringstream ssMapKey;
5295 ssMapKey << username <<
":" << activeSessionIndex;
5296 std::string mapKey = ssMapKey.str();
5297 __SUP_COUT__ <<
"Config Session: " << mapKey
5298 <<
" ... out of size: " << userConfigurationManagers_.size() << __E__;
5300 time_t now = time(0);
5303 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
5305 __SUP_COUT_INFO__ <<
"Creating new Configuration Manager." << __E__;
5306 userConfigurationManagers_[mapKey] =
new ConfigurationManagerRW(username);
5311 userConfigurationManagers_[mapKey]->getAllTableInfo(
5314 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
5316 __SUP_SS__ <<
"Fatal error managing userLastUseTime_!" << __E__;
5317 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5320 else if(refresh || (now - userLastUseTime_[mapKey]) >
5321 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
5325 __SUP_COUT_INFO__ <<
"Refreshing all table info." << __E__;
5326 userConfigurationManagers_[mapKey]->getAllTableInfo(
true);
5335 userLastUseTime_[mapKey] = now;
5338 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
5339 it != userLastUseTime_.end();
5341 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
5343 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
5345 delete userConfigurationManagers_[it->first];
5346 if(!(userConfigurationManagers_.erase(it->first)))
5348 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
5350 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5353 userLastUseTime_.erase(it);
5355 it = userLastUseTime_.begin();
5360 return userConfigurationManagers_[mapKey];
5382 void ConfigurationGUISupervisor::handleCreateTableGroupXML(
5383 HttpXmlDocument& xmlOut,
5384 ConfigurationManagerRW* cfgMgr,
5385 const std::string& groupName,
5386 const std::string& tableList,
5387 bool allowDuplicates,
5388 bool ignoreWarnings,
5389 const std::string& groupComment,
5390 bool lookForEquivalent)
try
5392 __SUP_COUT__ <<
"handleCreateTableGroupXML \n";
5394 xmlOut.addTextElementToData(
"AttemptedNewGroupName", groupName);
5398 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
true);
5399 cfgMgr->loadConfigurationBackbone();
5401 std::map<std::string ,
5402 std::map<std::string , TableVersion >>
5403 versionAliases = cfgMgr->getVersionAliases();
5409 std::map<std::string , TableVersion > groupMembers;
5410 std::map<std::string , std::string > groupAliases;
5412 std::string name, versionStr, alias;
5413 TableVersion version;
5414 auto c = tableList.find(
',', 0);
5417 while(c < tableList.length())
5420 name = tableList.substr(i, c - i);
5422 c = tableList.find(
',', i);
5423 if(c == std::string::npos)
5425 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
5426 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5427 xmlOut.addTextElementToData(
"Error", ss.str());
5431 versionStr = tableList.substr(i, c - i);
5433 c = tableList.find(
',', i);
5439 if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
5442 versionStr.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
5444 __SUP_COUT__ <<
"Found alias " << name <<
" " << versionStr << __E__;
5447 if(versionAliases.find(name) != versionAliases.end() &&
5448 versionAliases[name].find(alias) != versionAliases[name].end())
5450 version = versionAliases[name][alias];
5451 __SUP_COUT__ <<
"version alias '" << alias
5452 <<
"'translated to: " << version << __E__;
5454 groupAliases[name] = alias;
5458 __SUP_SS__ <<
"version alias '"
5459 << versionStr.substr(
5460 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
5461 <<
"' was not found in active version aliases!" << __E__;
5462 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5463 xmlOut.addTextElementToData(
"Error", ss.str());
5468 version = TableVersion(versionStr);
5470 if(version.isTemporaryVersion())
5472 __SUP_SS__ <<
"Groups can not be created using temporary member tables. "
5473 <<
"Table member '" << name <<
"' with temporary version '"
5474 << version <<
"' is illegal." << __E__;
5475 xmlOut.addTextElementToData(
"Error", ss.str());
5480 if(allTableInfo.find(name) == allTableInfo.end())
5482 __SUP_SS__ <<
"Groups can not be created using mock-up member tables of "
5483 "undefined tables. "
5484 <<
"Table member '" << name <<
"' is not defined." << __E__;
5485 xmlOut.addTextElementToData(
"Error", ss.str());
5489 if(version.isMockupVersion())
5492 TableBase* config = cfgMgr->getTableByName(name);
5494 TableVersion temporaryVersion = config->createTemporaryView();
5495 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << __E__;
5498 __SUP_COUT__ <<
"Creating version from mock-up for name: " << name
5499 <<
" inputVersionStr: " << versionStr << __E__;
5502 config->getTemporaryView(temporaryVersion)
5503 ->setComment(
"Auto-generated from mock-up.");
5507 saveModifiedVersionXML(xmlOut,
5517 __SUP_COUT__ <<
"Using mockup version: " << version << __E__;
5521 groupMembers[name] = version;
5524 __COUTV__(StringMacros::mapToString(groupAliases));
5526 if(!allowDuplicates)
5528 __SUP_COUT__ <<
"Checking for duplicate groups..." << __E__;
5529 TableGroupKey foundKey =
5530 cfgMgr->findTableGroup(groupName, groupMembers, groupAliases);
5532 if(!foundKey.isInvalid())
5535 xmlOut.addTextElementToData(
"TableGroupName", groupName);
5536 xmlOut.addTextElementToData(
"TableGroupKey", foundKey.toString());
5538 if(lookForEquivalent)
5540 __SUP_COUT__ <<
"Found equivalent group key (" << foundKey <<
") for "
5541 << groupName <<
"." << __E__;
5543 xmlOut.addTextElementToData(
"foundEquivalentKey",
"1");
5546 handleGetTableGroupXML(
5547 xmlOut, cfgMgr, groupName, foundKey, ignoreWarnings);
5552 __SUP_COUT__ <<
"Treating duplicate group as error." << __E__;
5553 __SUP_SS__ << (
"Failed to create table group: " + groupName +
5554 ". It is a duplicate of an existing group key (" +
5555 foundKey.toString() +
")");
5556 __SUP_COUT_ERR__ << ss.str() << __E__;
5557 xmlOut.addTextElementToData(
"Error", ss.str());
5562 __SUP_COUT__ <<
"Check for duplicate groups complete." << __E__;
5568 cfgMgr->loadMemberMap(groupMembers);
5570 std::string accumulateErrors =
"";
5571 for(
auto& groupMemberPair : groupMembers)
5573 TableView* cfgViewPtr =
5574 cfgMgr->getTableByName(groupMemberPair.first)->getViewP();
5575 if(cfgViewPtr->getDataColumnSize() != cfgViewPtr->getNumberOfColumns() ||
5576 cfgViewPtr->getSourceColumnMismatch() !=
5579 __SUP_SS__ <<
"\n\nThere were errors found in loading a member table "
5580 << groupMemberPair.first <<
":v" << cfgViewPtr->getVersion()
5581 <<
". Please see the details below:\n\n"
5582 <<
"The source column size was found to be "
5583 << cfgViewPtr->getDataColumnSize()
5584 <<
", and the current number of columns for this table is "
5585 << cfgViewPtr->getNumberOfColumns()
5586 <<
". This resulted in a count of "
5587 << cfgViewPtr->getSourceColumnMismatch()
5588 <<
" source column mismatches, and a count of "
5589 << cfgViewPtr->getSourceColumnMissing()
5590 <<
" table entries missing in "
5591 << cfgViewPtr->getNumberOfRows() <<
" row(s) of data."
5594 const std::set<std::string> srcColNames =
5595 cfgViewPtr->getSourceColumnNames();
5596 ss <<
"\n\nSource column names were as follows:\n";
5598 for(
auto& srcColName : srcColNames)
5599 ss <<
"\n\t" << index++ <<
". " << srcColName;
5602 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
5603 ss <<
"\n\nCurrent table column names are as follows:\n";
5605 for(
auto& destColName : destColNames)
5606 ss <<
"\n\t" << index++ <<
". " << destColName;
5609 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5610 xmlOut.addTextElementToData(
"Error", ss.str());
5615 catch(std::runtime_error& e)
5617 __SUP_SS__ <<
"Failed to create config group: " << groupName
5618 <<
".\nThere were problems loading the chosen members:\n\n"
5619 << e.what() << __E__;
5620 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5621 xmlOut.addTextElementToData(
"Error", ss.str());
5626 __SUP_SS__ <<
"Failed to create config group: " << groupName << __E__;
5627 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5628 xmlOut.addTextElementToData(
"Error", ss.str());
5633 std::string accumulateTreeErrs;
5634 cfgMgr->getChildren(&groupMembers, &accumulateTreeErrs);
5635 if(accumulateTreeErrs !=
"")
5637 __SUP_COUT_WARN__ <<
"\n" << accumulateTreeErrs << __E__;
5640 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
5645 TableGroupKey newKey;
5648 __COUT__ <<
"Saving new group..." << __E__;
5649 newKey = cfgMgr->saveNewTableGroup(
5650 groupName, groupMembers, groupComment, &groupAliases);
5652 catch(std::runtime_error& e)
5654 __SUP_COUT_ERR__ <<
"Failed to create config group: " << groupName << __E__;
5655 __SUP_COUT_ERR__ <<
"\n\n" << e.what() << __E__;
5656 xmlOut.addTextElementToData(
5657 "Error",
"Failed to create table group: " + groupName +
".\n\n" + e.what());
5662 __SUP_COUT_ERR__ <<
"Failed to create table group: " << groupName << __E__;
5663 xmlOut.addTextElementToData(
"Error",
5664 "Failed to create table group: " + groupName);
5669 __COUT__ <<
"Loading new table group..." << __E__;
5670 handleGetTableGroupXML(xmlOut, cfgMgr, groupName, newKey, ignoreWarnings);
5673 catch(std::runtime_error& e)
5675 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
5676 xmlOut.addTextElementToData(
"Error",
5677 "Error saving table group! " + std::string(e.what()));
5681 __SUP_COUT__ <<
"Unknown Error detected!\n\n " << __E__;
5682 xmlOut.addTextElementToData(
"Error",
"Error saving table group! ");
5690 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(HttpXmlDocument& xmlOut,
5691 ConfigurationManagerRW* cfgMgr,
5692 std::string& tableName)
5694 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
5695 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
5696 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
5697 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5701 __SUP_COUT_ERR__ << (
"Error renaming file to " +
5702 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5705 xmlOut.addTextElementToData(
5707 (
"Error renaming Table Info File to " +
5708 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
5713 cfgMgr->getAllTableInfo(
true);
5723 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
5724 HttpXmlDocument& xmlOut,
5725 ConfigurationManagerRW* cfgMgr,
5726 std::string& tableName,
5727 const std::string& data,
5728 const std::string& tableDescription,
5729 const std::string& columnChoicesCSV,
5730 bool allowOverwrite)
5734 std::string capsName;
5737 capsName = TableBase::convertToCaps(tableName,
true);
5739 catch(std::runtime_error& e)
5741 xmlOut.addTextElementToData(
"Error", e.what());
5747 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
5751 xmlOut.addTextElementToData(
"TableName", tableName);
5752 xmlOut.addTextElementToData(
"OverwriteError",
"1");
5753 xmlOut.addTextElementToData(
5755 "File already exists! ('" +
5756 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
5761 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
5762 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
5763 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
5764 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
5767 std::stringstream outss;
5769 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
5770 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
5771 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
5772 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
5773 outss <<
"\t\t\t<VIEW Name=\"" << capsName
5774 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
5780 int j = data.find(
',', i);
5781 int k = data.find(
';', i);
5783 std::istringstream columnChoicesISS(columnChoicesCSV);
5784 std::string columnChoicesString;
5785 std::string columnType;
5787 while(k != (
int)(std::string::npos))
5790 columnType = data.substr(i, j - i);
5791 outss <<
"\t\t\t\t<COLUMN Type=\"";
5792 outss << columnType;
5795 j = data.find(
',', i);
5798 outss <<
"\" \t Name=\"";
5799 capsName = data.substr(i, j - i);
5801 outss <<
"\" \t StorageName=\"";
5805 outss << TableBase::convertToCaps(capsName);
5807 catch(std::runtime_error& e)
5809 xmlOut.addTextElementToData(
"Error",
5810 std::string(
"For column name '") +
5811 data.substr(i, j - i) +
"' - " + e.what());
5816 j = data.find(
',', i);
5819 outss <<
"\" \t DataType=\"";
5820 outss << data.substr(i, k - i);
5823 getline(columnChoicesISS, columnChoicesString,
';');
5825 outss <<
"\" \t DataChoices=\"";
5826 outss << columnChoicesString;
5832 j = data.find(
',', i);
5833 k = data.find(
';', i);
5836 outss <<
"\t\t\t</VIEW>\n";
5837 outss <<
"\t\t</TABLE>\n";
5838 outss <<
"\t</ROOT>\n";
5840 __SUP_COUT__ << outss.str() << __E__;
5842 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
5845 xmlOut.addTextElementToData(
"Error",
5846 "Failed to open destination Table Info file:" +
5847 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
5851 fprintf(fp,
"%s", outss.str().c_str());
5856 std::string accumulatedErrors =
"";
5857 cfgMgr->getAllTableInfo(
true, &accumulatedErrors, tableName);
5860 if(accumulatedErrors !=
"")
5862 __SUP_SS__ << (
"The new version of the '" + tableName +
5863 "' table column info was saved, however errors were detected "
5864 "reading back the table '" +
5865 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
5868 __SUP_COUT_ERR__ << ss.str() << __E__;
5869 xmlOut.addTextElementToData(
"Error", ss.str());
5881 rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
5882 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
5884 << (
"File successfully renamed: " +
5885 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5890 << (
"Error renaming file to " +
5891 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5895 cfgMgr->getAllTableInfo(
true);
5901 handleGetTableXML(xmlOut, cfgMgr, tableName, TableVersion());
5905 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
5908 __SUP_COUT_INFO__ <<
"Looking for errors in all table column info..." << __E__;
5909 for(
const auto& cfgInfo : allTableInfo)
5913 cfgMgr->getTableByName(cfgInfo.first)->getMockupViewP()->init();
5915 catch(std::runtime_error& e)
5917 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
5918 <<
"Error identified in column info of table '"
5919 << cfgInfo.first <<
"':\n\n"
5920 << e.what() <<
"\n\n"
5934 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
5935 HttpXmlDocument& xmlOut,
5936 ConfigurationManagerRW* cfgMgr,
5937 const std::string& groupAlias,
5938 const std::string& groupName,
5939 TableGroupKey groupKey,
5940 const std::string& author)
try
5942 cfgMgr->loadConfigurationBackbone();
5943 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
5945 const std::string groupAliasesTableName =
5946 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
5947 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
5949 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
5951 xmlOut.addTextElementToData(
"Error", ss.str());
5956 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
5957 for(
auto& memberName : backboneMembers)
5959 __SUP_COUT__ <<
"activeVersions[\"" << memberName
5960 <<
"\"]=" << activeVersions[memberName] << __E__;
5962 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
5963 xmlOut.addTextElementToData(
"oldBackboneVersion",
5964 activeVersions[memberName].toString());
5971 TableBase* config = cfgMgr->getTableByName(groupAliasesTableName);
5972 TableVersion originalVersion = activeVersions[groupAliasesTableName];
5973 TableVersion temporaryVersion = config->createTemporaryView(originalVersion);
5975 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
5976 bool isDifferent =
false;
5980 TableView* configView = config->getTemporaryView(temporaryVersion);
5982 unsigned int col = configView->findCol(
"GroupKeyAlias");
5986 unsigned int row = -1;
5990 row = configView->findRow(col, groupAlias);
5995 if(row == (
unsigned int)-1)
5998 row = configView->addRow();
6001 col = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6002 configView->setValue(
6003 "This Group Alias was automatically setup by the server.", row, col);
6004 col = configView->findCol(
"GroupKeyAlias");
6005 configView->setValue(groupAlias, row, col);
6008 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6010 col = configView->findCol(
"GroupName");
6012 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6013 << configView->getDataView()[row][col] << __E__;
6014 if(groupName != configView->getDataView()[row][col])
6016 configView->setValue(groupName, row, col);
6020 col = configView->findCol(
"GroupKey");
6021 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6022 << configView->getDataView()[row][col] << __E__;
6023 if(groupKey.toString() != configView->getDataView()[row][col])
6025 configView->setValue(groupKey.toString(), row, col);
6031 configView->setValue(author, row, configView->findCol(
"Author"));
6032 configView->setValue(
6033 time(0), row, configView->findCol(
"RecordInsertionTime"));
6038 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6041 config->eraseView(temporaryVersion);
6045 TableVersion newAssignedVersion;
6048 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6056 newAssignedVersion = saveModifiedVersionXML(xmlOut,
6058 config->getTableName(),
6069 <<
"\t\t**************************** Using the existing table version"
6073 config->eraseView(temporaryVersion);
6074 newAssignedVersion = activeVersions[groupAliasesTableName];
6076 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6077 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6080 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6082 catch(std::runtime_error& e)
6084 __SUP_COUT_ERR__ <<
"Error detected!\n\n " << e.what() << __E__;
6085 xmlOut.addTextElementToData(
6086 "Error",
"Error saving new Group Alias view!\n " + std::string(e.what()));
6090 __SUP_COUT_ERR__ <<
"Error detected!\n\n " << __E__;
6091 xmlOut.addTextElementToData(
"Error",
"Error saving new Group Alias view! ");
6102 void ConfigurationGUISupervisor::handleSetVersionAliasInBackboneXML(
6103 HttpXmlDocument& xmlOut,
6104 ConfigurationManagerRW* cfgMgr,
6105 const std::string& versionAlias,
6106 const std::string& tableName,
6107 TableVersion version,
6108 const std::string& author)
try
6110 cfgMgr->loadConfigurationBackbone();
6111 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6113 const std::string versionAliasesTableName =
6114 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6115 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6117 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6119 xmlOut.addTextElementToData(
"Error", ss.str());
6124 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6125 for(
auto& memberName : backboneMembers)
6127 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6128 <<
"\"]=" << activeVersions[memberName] << __E__;
6130 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6131 xmlOut.addTextElementToData(
"oldBackboneVersion",
6132 activeVersions[memberName].toString());
6139 TableBase* config = cfgMgr->getTableByName(versionAliasesTableName);
6140 TableVersion originalVersion = activeVersions[versionAliasesTableName];
6141 TableVersion temporaryVersion = config->createTemporaryView(originalVersion);
6143 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6145 bool isDifferent =
false;
6149 TableView* configView = config->getTemporaryView(temporaryVersion);
6152 unsigned int col2 = configView->findCol(
"VersionAlias");
6153 unsigned int col3 = configView->findCol(
"TableName");
6157 unsigned int row = -1;
6162 unsigned int tmpRow = -1;
6165 tmpRow = configView->findRow(col3, tableName, tmpRow + 1);
6166 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
6173 if(row == (
unsigned int)-1)
6176 row = configView->addRow();
6179 col = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6180 configView->setValue(
6181 std::string(
"Entry was added by server in ") +
6182 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone().",
6186 col = configView->findCol(
"VersionAliasUID");
6187 configView->setValue(
6188 tableName.substr(0, tableName.rfind(
"Table")) + versionAlias, row, col);
6190 configView->setValue(versionAlias, row, col2);
6191 configView->setValue(tableName, row, col3);
6194 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6196 col = configView->findCol(
"Version");
6197 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
6198 << configView->getDataView()[row][col] << __E__;
6199 if(version.toString() != configView->getDataView()[row][col])
6201 configView->setValue(version.toString(), row, col);
6207 configView->setValue(author, row, configView->findCol(
"Author"));
6208 configView->setValue(
6209 time(0), row, configView->findCol(
"RecordInsertionTime"));
6214 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
6217 config->eraseView(temporaryVersion);
6221 TableVersion newAssignedVersion;
6224 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6230 newAssignedVersion = saveModifiedVersionXML(xmlOut,
6232 config->getTableName(),
6242 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
6246 config->eraseView(temporaryVersion);
6247 newAssignedVersion = activeVersions[versionAliasesTableName];
6249 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
6250 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6253 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6255 catch(std::runtime_error& e)
6257 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
6258 xmlOut.addTextElementToData(
6259 "Error",
"Error saving new Version Alias view!\n " + std::string(e.what()));
6263 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
6264 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
6273 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
6274 HttpXmlDocument& xmlOut,
6275 ConfigurationManagerRW* cfgMgr,
6276 const std::string& versionAlias,
6277 const std::string& groupName,
6278 TableGroupKey groupKey,
6279 const std::string& author)
try
6281 cfgMgr->loadConfigurationBackbone();
6282 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6284 const std::string versionAliasesTableName =
6285 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6286 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6288 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6290 xmlOut.addTextElementToData(
"Error", ss.str());
6295 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6296 for(
auto& memberName : backboneMembers)
6298 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6299 <<
"\"]=" << activeVersions[memberName] << __E__;
6301 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6302 xmlOut.addTextElementToData(
"oldBackboneVersion",
6303 activeVersions[memberName].toString());
6310 TableBase* config = cfgMgr->getTableByName(versionAliasesTableName);
6311 TableVersion temporaryVersion =
6312 config->createTemporaryView(activeVersions[versionAliasesTableName]);
6314 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6316 TableView* configView = config->getTemporaryView(temporaryVersion);
6319 bool isDifferent =
false;
6322 std::map<std::string , TableVersion > memberMap;
6325 cfgMgr->loadTableGroup(groupName,
6338 xmlOut.addTextElementToData(
6340 "Table group \"" + TableGroupKey::getFullGroupString(groupName, groupKey) +
6341 "\" can not be retrieved!");
6346 unsigned int col2 = configView->findCol(
"VersionAlias");
6347 unsigned int col3 = configView->findCol(
"TableName");
6349 for(
auto& memberPair : memberMap)
6351 bool thisMemberIsDifferent =
false;
6352 unsigned int row = -1;
6354 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
6355 << memberPair.second <<
" to " << versionAlias << __E__;
6361 unsigned int tmpRow = -1;
6364 tmpRow = configView->findRow(col3, memberPair.first, tmpRow + 1);
6367 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
6374 if(row == (
unsigned int)-1)
6376 thisMemberIsDifferent =
true;
6377 row = configView->addRow();
6380 col = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6381 configView->setValue(
6382 std::string(
"Entry was added by server in ") +
6383 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone().",
6387 col = configView->getColUID();
6388 configView->setValue(
6389 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
6394 configView->setValue(versionAlias, row, col2);
6395 configView->setValue(memberPair.first, row, col3);
6400 col = configView->findCol(
"Version");
6404 if(memberPair.second.toString() != configView->getDataView()[row][col])
6406 configView->setValue(memberPair.second.toString(), row, col);
6407 thisMemberIsDifferent =
true;
6410 if(thisMemberIsDifferent)
6412 configView->setValue(author, row, configView->findCol(
"Author"));
6413 configView->setValue(
6414 time(0), row, configView->findCol(
"RecordInsertionTime"));
6417 if(thisMemberIsDifferent)
6423 TableVersion newAssignedVersion;
6426 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
6427 <<
" as new table version" << __E__;
6429 newAssignedVersion =
6430 cfgMgr->saveNewTable(versionAliasesTableName, temporaryVersion);
6434 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
6438 config->eraseView(temporaryVersion);
6439 newAssignedVersion = activeVersions[versionAliasesTableName];
6442 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
6443 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6444 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
6446 catch(std::runtime_error& e)
6448 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
6449 xmlOut.addTextElementToData(
6450 "Error",
"Error saving new Version Alias view!\n " + std::string(e.what()));
6454 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
6455 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
6469 void ConfigurationGUISupervisor::handleGroupAliasesXML(HttpXmlDocument& xmlOut,
6470 ConfigurationManagerRW* cfgMgr)
6472 cfgMgr->loadConfigurationBackbone();
6473 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6475 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6476 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6478 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
6479 << groupAliasesTableName
6480 <<
" is a required member of the Backbone table group."
6481 <<
"\n\nLikely you need to activate a valid Backbone table group."
6483 xmlOut.addTextElementToData(
"Error", ss.str());
6486 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
6487 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
6488 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
6489 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
6490 activeVersions[groupAliasesTableName].toString());
6492 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
6493 cfgMgr->getNode(groupAliasesTableName).getChildren();
6495 std::string groupName, groupKey, groupComment, groupType;
6496 for(
auto& aliasNodePair : aliasNodePairs)
6498 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
6499 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
6501 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
6502 xmlOut.addTextElementToData(
"GroupName", groupName);
6503 xmlOut.addTextElementToData(
"GroupKey", groupKey);
6504 xmlOut.addTextElementToData(
6506 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
6507 .getValueAsString());
6511 groupType =
"Invalid";
6514 cfgMgr->loadTableGroup(groupName,
6515 TableGroupKey(groupKey),
6528 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"(" << groupKey
6529 <<
")' to extract group comment and type." << __E__;
6531 xmlOut.addTextElementToData(
"GroupComment", groupComment);
6532 xmlOut.addTextElementToData(
"GroupType", groupType);
6547 void ConfigurationGUISupervisor::handleVersionAliasesXML(HttpXmlDocument& xmlOut,
6548 ConfigurationManagerRW* cfgMgr)
6550 cfgMgr->loadConfigurationBackbone();
6551 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6553 std::string versionAliasesTableName =
6554 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6555 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6557 __SUP_SS__ <<
"Active version of VersionAliases missing!"
6558 <<
"Make sure you have a valid active Backbone Group." << __E__;
6559 xmlOut.addTextElementToData(
"Error", ss.str());
6562 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
6563 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
6564 xmlOut.addTextElementToData(
"VersionAliasesVersion",
6565 activeVersions[versionAliasesTableName].toString());
6567 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
6568 cfgMgr->getNode(versionAliasesTableName).getChildren();
6570 for(
auto& aliasNodePair : aliasNodePairs)
6574 xmlOut.addTextElementToData(
6576 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
6577 xmlOut.addTextElementToData(
6578 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
6579 xmlOut.addTextElementToData(
6580 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
6581 xmlOut.addTextElementToData(
6583 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
6584 .getValueAsString());
6594 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
6595 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr,
const std::string& tableList)
6597 std::map<std::string , TableVersion > memberMap;
6598 std::string name, versionStr;
6599 auto c = tableList.find(
',', 0);
6602 while(c < tableList.length())
6605 name = tableList.substr(i, c - i);
6607 c = tableList.find(
',', i);
6608 if(c == std::string::npos)
6610 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
6611 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6612 xmlOut.addTextElementToData(
"Error", ss.str());
6616 versionStr = tableList.substr(i, c - i);
6618 c = tableList.find(
',', i);
6620 memberMap[name] = TableVersion(versionStr);
6623 std::string groupTypeString =
"";
6628 groupTypeString = cfgMgr->getTypeNameOfGroup(memberMap);
6629 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6631 catch(std::runtime_error& e)
6633 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
6634 __SUP_COUT__ <<
"\n" << ss.str();
6635 groupTypeString =
"Invalid";
6636 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6640 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
6641 __SUP_COUT__ <<
"\n" << ss.str();
6642 groupTypeString =
"Invalid";
6643 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6663 void ConfigurationGUISupervisor::handleTableGroupsXML(HttpXmlDocument& xmlOut,
6664 ConfigurationManagerRW* cfgMgr,
6667 DOMElement* parentEl;
6671 if(!cfgMgr->getAllGroupInfo()
6674 __SUP_COUT__ <<
"Cache is empty? Attempting to regenerate." << __E__;
6675 cfgMgr->getAllTableInfo(
true );
6678 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
6698 TableGroupKey groupKey;
6699 std::string groupName;
6700 std::string groupString, groupTypeString, groupComment, groupCreationTime,
6702 for(
auto& groupInfo : allGroupInfo)
6704 groupName = groupInfo.first;
6705 if(groupInfo.second.keys_.size() == 0)
6707 __SUP_COUT__ <<
"Group name '" << groupName
6708 <<
"' found, but no keys so ignoring." << __E__;
6712 groupKey = *(groupInfo.second.keys_.rbegin());
6714 xmlOut.addTextElementToData(
"TableGroupName", groupName);
6715 xmlOut.addTextElementToData(
"TableGroupKey", groupKey.toString());
6718 xmlOut.addTextElementToData(
"TableGroupType",
6719 groupInfo.second.latestKeyGroupTypeString_);
6720 xmlOut.addTextElementToData(
"TableGroupComment",
6721 groupInfo.second.latestKeyGroupComment_);
6722 xmlOut.addTextElementToData(
"TableGroupAuthor",
6723 groupInfo.second.latestKeyGroupAuthor_);
6724 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6725 groupInfo.second.latestKeyGroupCreationTime_);
6738 parentEl = xmlOut.addTextElementToData(
"TableGroupMembers",
"");
6778 for(
auto& memberPair : groupInfo.second.latestKeyMemberMap_)
6782 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
6783 xmlOut.addTextElementToParent(
6784 "MemberVersion", memberPair.second.toString(), parentEl);
6790 for(
auto& keyInSet : groupInfo.second.keys_)
6792 if(keyInSet == groupKey)
6794 xmlOut.addTextElementToData(
"TableGroupName", groupName);
6795 xmlOut.addTextElementToData(
"TableGroupKey", keyInSet.toString());
6798 xmlOut.addTextElementToData(
"TableGroupType",
6799 groupInfo.second.latestKeyGroupTypeString_);
6800 xmlOut.addTextElementToData(
"TableGroupComment",
6801 groupInfo.second.latestKeyGroupComment_);
6802 xmlOut.addTextElementToData(
"TableGroupAuthor",
6803 groupInfo.second.latestKeyGroupAuthor_);
6804 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6805 groupInfo.second.latestKeyGroupCreationTime_);
6809 xmlOut.addTextElementToData(
"TableGroupMembers",
"");
6812 bool loadingHistoricalInfo =
false;
6813 if(loadingHistoricalInfo)
6818 cfgMgr->loadTableGroup(groupName,
6832 groupTypeString =
"Invalid";
6834 <<
"Failed to load group '" << groupName <<
"(" << keyInSet
6835 <<
")' to extract group comment and type." << __E__;
6838 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6839 xmlOut.addTextElementToData(
"TableGroupComment", groupComment);
6840 xmlOut.addTextElementToData(
"TableGroupAuthor", groupAuthor);
6841 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6862 void ConfigurationGUISupervisor::handleTablesXML(HttpXmlDocument& xmlOut,
6863 ConfigurationManagerRW* cfgMgr,
6864 bool allowIllegalColumns)
6866 DOMElement* parentEl;
6868 std::string accumulatedErrors =
"";
6869 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
6870 allowIllegalColumns,
6871 allowIllegalColumns ? &accumulatedErrors
6873 std::map<std::string, TableInfo>::const_iterator it = allTableInfo.begin();
6875 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
6877 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
6878 cfgMgr->getVersionAliases();
6880 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
6882 while(it != allTableInfo.end())
6891 xmlOut.addTextElementToData(
"TableName", it->first);
6892 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6895 if(versionAliases.find(it->first) != versionAliases.end())
6896 for(
auto& aliasVersion : versionAliases[it->first])
6897 if(it->second.versions_.find(aliasVersion.second) !=
6898 it->second.versions_.end())
6902 xmlOut.addTextElementToParent(
6904 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
6922 for(
auto& version : it->second.versions_)
6923 if(!version.isScratchVersion())
6924 xmlOut.addTextElementToParent(
"Version", version.toString(), parentEl);
6929 if(accumulatedErrors !=
"")
6930 xmlOut.addTextElementToData(
6932 std::string(
"Column errors were allowed for this request, ") +
6933 "but please note the following errors:\n" + accumulatedErrors);
6939 void ConfigurationGUISupervisor::testXDAQContext()
6943 __SUP_COUT__ <<
"Attempting test activation of the context group." << __E__;
6944 ConfigurationManager cfgMgr;
6946 catch(
const std::runtime_error& e)
6949 <<
"The test activation of the context group failed. Ignoring error: \n"
6950 << e.what() << __E__;
6954 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)