1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
2 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 #include "otsdaq-core/TablePluginDataFormats/IterateTable.h"
6 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
8 #if MESSAGEFACILITY_HEX_VERSION > 0x20100
9 #include <boost/stacktrace.hpp>
12 #include "otsdaq-core/TablePluginDataFormats/XDAQContextTable.h"
14 #include <xdaq/NamespaceURI.h>
23 #define __MF_SUBJECT__ "CfgGUI"
25 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
26 #define TABLE_INFO_EXT std::string("Info.xml")
39 ConfigurationGUISupervisor::ConfigurationGUISupervisor(xdaq::ApplicationStub* stub)
40 : CoreSupervisorBase(stub)
42 __SUP_COUT__ <<
"Constructor started." << __E__;
44 INIT_MF(
"ConfigurationGUI");
47 __SUP_COUT__ <<
"Constructor complete." << __E__;
51 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
54 void ConfigurationGUISupervisor::init(
void)
56 __SUP_COUT__ <<
"Initializing..." << __E__;
58 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
66 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
67 "will not launch when this test fails. "
68 <<
"Check the active context group from within Wizard Mode."
74 void ConfigurationGUISupervisor::destroy(
void)
77 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
78 userConfigurationManagers_.begin();
79 it != userConfigurationManagers_.end();
85 userConfigurationManagers_.clear();
89 if(ConfigurationInterface::getInstance(
true) != 0)
90 delete ConfigurationInterface::getInstance(
true);
94 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
96 cgicc::Cgicc cgiIn(in);
97 std::string configWindowName =
98 CgiDataUtilities::getData(cgiIn,
"configWindowName");
99 if(configWindowName ==
"tableEditor")
100 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
101 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
102 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
103 if(configWindowName ==
"iterate")
104 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
105 "src='/WebPath/html/Iterate.html?urn="
106 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
108 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
109 "src='/WebPath/html/ConfigurationGUI.html?urn="
110 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
116 void ConfigurationGUISupervisor::setSupervisorPropertyDefaults(
void)
118 CorePropertySupervisorBase::setSupervisorProperty(
119 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
120 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
121 "deleteTableInfo=255");
122 CorePropertySupervisorBase::setSupervisorProperty(
123 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
130 void ConfigurationGUISupervisor::forceSupervisorPropertyValues()
132 CorePropertySupervisorBase::setSupervisorProperty(
133 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
135 CorePropertySupervisorBase::setSupervisorProperty(
136 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
141 void ConfigurationGUISupervisor::request(
const std::string& requestType,
143 HttpXmlDocument& xmlOut,
144 const WebUsers::RequestUserInfo& userInfo)
try
197 std::string refresh = CgiDataUtilities::getData(cgiIn,
"refresh");
201 ConfigurationManagerRW* cfgMgr = refreshUserSession(
202 userInfo.username_, userInfo.activeUserSessionIndex_, (refresh ==
"1"));
204 if(requestType ==
"saveTableInfo")
206 std::string tableName =
207 CgiDataUtilities::getData(cgiIn,
"tableName");
208 std::string columnCSV =
209 CgiDataUtilities::postData(cgiIn,
"columnCSV");
210 std::string allowOverwrite =
211 CgiDataUtilities::getData(cgiIn,
"allowOverwrite");
212 std::string tableDescription =
213 CgiDataUtilities::postData(cgiIn,
"tableDescription");
214 std::string columnChoicesCSV =
215 CgiDataUtilities::postData(cgiIn,
"columnChoicesCSV");
220 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
221 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
222 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
223 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
224 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
226 if(!allSupervisorInfo_.isWizardMode())
228 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
229 xmlOut.addTextElementToData(
"Error", ss.str());
232 handleSaveTableInfoXML(xmlOut,
238 allowOverwrite ==
"1");
240 else if(requestType ==
"deleteTableInfo")
242 std::string tableName =
243 CgiDataUtilities::getData(cgiIn,
"tableName");
244 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
245 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
247 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
248 requestType ==
"flattenToSystemAliases")
251 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
252 __MOUT_WARN__ << requestType <<
" command received! " << __E__;
255 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
257 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
258 std::vector<std::string> hostnames;
261 if(requestType ==
"flattenToSystemAliases" &&
262 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
264 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
265 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
273 const XDAQContextTable* contextTable =
274 cfgMgr->__GET_CONFIG__(XDAQContextTable);
276 auto contexts = contextTable->getContexts();
278 for(
const auto& context : contexts)
285 for(i = 0; i < context.address_.size(); ++i)
286 if(context.address_[i] ==
'/')
288 hostnames.push_back(context.address_.substr(j));
289 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
294 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
298 __SUP_COUT_ERR__ <<
"\n" << ss.str();
303 if(hostnames.size() == 0)
305 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
306 "'... Is there a valid Context group activated?"
308 __SUP_COUT_ERR__ <<
"\n" << ss.str();
310 xmlOut.addTextElementToData(
"Error", ss.str());
313 for(
const auto& hostname : hostnames)
315 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
316 "/StartOTS_action_" + hostname +
".cmd");
317 FILE* fp = fopen(fn.c_str(),
"w");
320 if(requestType ==
"gatewayLaunchOTS")
321 fprintf(fp,
"LAUNCH_OTS");
322 else if(requestType ==
"gatewayLaunchWiz")
323 fprintf(fp,
"LAUNCH_WIZ");
324 else if(requestType ==
"flattenToSystemAliases")
326 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
334 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
387 else if(requestType ==
"versionTracking")
389 std::string type = CgiDataUtilities::getData(cgiIn,
"Type");
390 __SUP_COUT__ <<
"type: " << type << __E__;
393 xmlOut.addTextElementToData(
394 "versionTrackingStatus",
395 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
396 else if(type ==
"ON")
398 ConfigurationInterface::setVersionTrackingEnabled(
true);
399 xmlOut.addTextElementToData(
400 "versionTrackingStatus",
401 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
403 else if(type ==
"OFF")
405 ConfigurationInterface::setVersionTrackingEnabled(
false);
406 xmlOut.addTextElementToData(
407 "versionTrackingStatus",
408 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
411 else if(requestType ==
"getColumnTypes")
414 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
415 std::vector<std::string> allDataTypes =
416 TableViewColumnInfo::getAllDataTypesForGUI();
417 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
418 TableViewColumnInfo::getAllDefaultsForGUI();
420 for(
const auto& type : allTypes)
421 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
422 for(
const auto& dataType : allDataTypes)
423 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
425 for(
const auto& colDefault : allDefaults)
427 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
428 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
429 colDefault.first.second);
430 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
433 else if(requestType ==
"getGroupAliases")
438 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
440 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
441 bool wasError =
false;
446 cfgMgr->clearAllCachedVersions();
447 cfgMgr->restoreActiveTableGroups(
true);
449 catch(std::runtime_error& e)
451 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
453 __SUP_COUT_ERR__ <<
"\n" << ss.str();
454 xmlOut.addTextElementToData(
"Error", ss.str());
459 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
460 __SUP_COUT_ERR__ <<
"\n" << ss.str();
461 xmlOut.addTextElementToData(
"Error", ss.str());
466 handleGroupAliasesXML(xmlOut, cfgMgr);
468 else if(requestType ==
"setGroupAliasInActiveBackbone")
470 std::string groupAlias =
471 CgiDataUtilities::getData(cgiIn,
"groupAlias");
472 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
474 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
476 __SUP_COUT__ <<
"groupAlias: " << groupAlias << __E__;
477 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
478 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
480 handleSetGroupAliasInBackboneXML(xmlOut,
484 TableGroupKey(groupKey),
487 else if(requestType ==
"setVersionAliasInActiveBackbone")
489 std::string versionAlias =
490 CgiDataUtilities::getData(cgiIn,
"versionAlias");
491 std::string tableName =
492 CgiDataUtilities::getData(cgiIn,
"tableName");
493 std::string version = CgiDataUtilities::getData(cgiIn,
"version");
495 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
496 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
497 __SUP_COUT__ <<
"version: " << version << __E__;
499 handleSetVersionAliasInBackboneXML(xmlOut,
503 TableVersion(version),
506 else if(requestType ==
"setAliasOfGroupMembers")
508 std::string versionAlias =
509 CgiDataUtilities::getData(cgiIn,
"versionAlias");
510 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
512 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
514 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
515 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
516 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
518 handleAliasGroupMembersInBackboneXML(xmlOut,
522 TableGroupKey(groupKey),
525 else if(requestType ==
"getVersionAliases")
527 handleVersionAliasesXML(xmlOut, cfgMgr);
529 else if(requestType ==
"getTableGroups")
531 bool doNotReturnMembers =
532 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
536 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
537 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
539 else if(requestType ==
"getTableGroupType")
541 std::string tableList =
542 CgiDataUtilities::postData(cgiIn,
"tableList");
543 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
545 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
547 else if(requestType ==
"getTables")
549 std::string allowIllegalColumns =
550 CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
552 __SUP_COUT__ <<
"allowIllegalColumns: " << allowIllegalColumns << __E__;
554 handleTablesXML(xmlOut, cfgMgr, allowIllegalColumns ==
"1");
556 else if(requestType ==
"getContextMemberNames")
558 std::set<std::string> members = cfgMgr->getContextMemberNames();
560 for(
auto& member : members)
561 xmlOut.addTextElementToData(
"ContextMember", member);
563 else if(requestType ==
"getBackboneMemberNames")
565 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
567 for(
auto& member : members)
568 xmlOut.addTextElementToData(
"BackboneMember", member);
570 else if(requestType ==
"getIterateMemberNames")
572 std::set<std::string> members = cfgMgr->getIterateMemberNames();
574 for(
auto& member : members)
575 xmlOut.addTextElementToData(
"IterateMember", member);
577 else if(requestType ==
"getSpecificTableGroup")
579 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
581 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
583 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
584 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
586 handleGetTableGroupXML(xmlOut, cfgMgr, groupName, TableGroupKey(groupKey));
588 else if(requestType ==
"saveNewTableGroup")
590 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
592 bool ignoreWarnings =
593 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
594 bool allowDuplicates =
595 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
596 bool lookForEquivalent =
597 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
598 std::string tableList =
599 CgiDataUtilities::postData(cgiIn,
"tableList");
600 std::string comment =
601 CgiDataUtilities::getData(cgiIn,
"groupComment");
603 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
604 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
605 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
606 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
607 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
608 __SUP_COUT__ <<
"comment: " << comment << __E__;
610 handleCreateTableGroupXML(xmlOut,
619 else if(requestType ==
"getSpecificTable")
621 std::string tableName =
622 CgiDataUtilities::getData(cgiIn,
"tableName");
623 std::string versionStr = CgiDataUtilities::getData(cgiIn,
"version");
624 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
625 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
627 std::string allowIllegalColumns =
628 CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
629 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
631 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
632 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
635 TableVersion version;
636 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
637 std::string versionAlias;
639 if(allTableInfo.find(tableName) != allTableInfo.end())
641 if(versionStr ==
"" &&
642 allTableInfo.at(tableName).versions_.size())
643 version = *(allTableInfo.at(tableName).versions_.rbegin());
644 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
647 std::map<std::string ,
648 std::map<std::string , TableVersion>>
649 versionAliases = cfgMgr->getVersionAliases();
651 versionAlias = versionStr.substr(
652 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
663 if(versionAliases.find(tableName) != versionAliases.end() &&
664 versionAliases[tableName].find(versionStr.substr(
665 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())) !=
666 versionAliases[tableName].end())
668 version = versionAliases[tableName][versionStr.substr(
669 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())];
670 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
675 << versionStr.substr(
676 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
677 <<
"'was not found in active version aliases!" << __E__;
680 version = atoi(versionStr.c_str());
683 __SUP_COUT__ <<
"version: " << version << __E__;
685 handleGetTableXML(xmlOut,
688 TableVersion(version),
689 (allowIllegalColumns ==
"1"));
691 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
693 else if(requestType ==
"saveSpecificTable")
695 std::string tableName =
696 CgiDataUtilities::getData(cgiIn,
"tableName");
697 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
698 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
699 bool sourceTableAsIs =
700 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
701 bool lookForEquivalent =
702 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
703 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
704 std::string comment =
705 CgiDataUtilities::getData(cgiIn,
"tableComment");
707 std::string data = CgiDataUtilities::postData(cgiIn,
"data");
711 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
712 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
714 __SUP_COUT__ <<
"comment: " << comment << __E__;
715 __SUP_COUT__ <<
"data: " << data << __E__;
716 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
717 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
719 handleCreateTableXML(xmlOut,
722 TableVersion(version),
731 else if(requestType ==
"clearTableTemporaryVersions")
733 std::string tableName =
734 CgiDataUtilities::getData(cgiIn,
"tableName");
735 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
739 cfgMgr->eraseTemporaryVersion(tableName);
741 catch(std::runtime_error& e)
743 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
744 xmlOut.addTextElementToData(
745 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
749 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
750 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
753 else if(requestType ==
"clearTableCachedVersions")
755 std::string tableName =
756 CgiDataUtilities::getData(cgiIn,
"tableName");
757 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
761 cfgMgr->clearCachedVersions(tableName);
763 catch(std::runtime_error& e)
765 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
766 xmlOut.addTextElementToData(
767 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
771 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
772 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
775 else if(requestType ==
"getTreeView")
777 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
778 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
779 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
780 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
781 std::string filterList = CgiDataUtilities::postData(cgiIn,
"filterList");
782 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
783 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
785 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
786 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
787 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
788 __SUP_COUT__ <<
"depth: " << depth << __E__;
789 __SUP_COUT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
790 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
791 __SUP_COUT__ <<
"filterList: " << filterList << __E__;
793 handleFillTreeViewXML(xmlOut,
796 TableGroupKey(configGroupKey),
803 else if(requestType ==
"getTreeNodeCommonFields")
805 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
806 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
807 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
808 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
809 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
810 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
811 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
813 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
814 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
815 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
816 __SUP_COUT__ <<
"depth: " << depth << __E__;
817 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
818 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
819 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
821 handleFillTreeNodeCommonFieldsXML(xmlOut,
824 TableGroupKey(configGroupKey),
831 else if(requestType ==
"getUniqueFieldValuesForRecords")
833 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
834 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
835 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
836 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
837 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
838 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
840 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
841 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
842 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
843 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
844 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
845 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
847 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
850 TableGroupKey(configGroupKey),
856 else if(requestType ==
"getTreeNodeFieldValues")
858 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
859 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
860 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
861 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
862 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
863 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
865 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
866 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
867 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
868 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
869 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
870 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
872 handleFillGetTreeNodeFieldValuesXML(xmlOut,
875 TableGroupKey(configGroupKey),
881 else if(requestType ==
"setTreeNodeFieldValues")
883 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
884 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
885 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
886 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
887 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
888 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
889 std::string valueList = CgiDataUtilities::postData(cgiIn,
"valueList");
891 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
892 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
893 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
894 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
895 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
896 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
897 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
899 handleFillSetTreeNodeFieldValuesXML(xmlOut,
902 TableGroupKey(configGroupKey),
910 else if(requestType ==
"addTreeNodeRecords")
912 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
913 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
914 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
915 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
916 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
918 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
919 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
920 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
921 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
922 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
924 handleFillCreateTreeNodeRecordsXML(xmlOut,
927 TableGroupKey(configGroupKey),
933 else if(requestType ==
"deleteTreeNodeRecords")
935 std::string configGroup = CgiDataUtilities::getData(cgiIn,
"configGroup");
936 std::string configGroupKey = CgiDataUtilities::getData(cgiIn,
"configGroupKey");
937 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
938 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
939 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
941 __SUP_COUT__ <<
"configGroup: " << configGroup << __E__;
942 __SUP_COUT__ <<
"configGroupKey: " << configGroupKey << __E__;
943 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
944 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
945 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
947 handleFillDeleteTreeNodeRecordsXML(xmlOut,
950 TableGroupKey(configGroupKey),
955 else if(requestType ==
"getAffectedActiveGroups")
957 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
958 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
959 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
960 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
961 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
962 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
964 handleGetAffectedGroupsXML(
965 xmlOut, cfgMgr, groupName, TableGroupKey(groupKey), modifiedTables);
967 else if(requestType ==
"saveTreeNodeEdit")
969 std::string editNodeType = CgiDataUtilities::getData(cgiIn,
"editNodeType");
970 std::string targetTable = CgiDataUtilities::getData(cgiIn,
"targetTable");
971 std::string targetTableVersion =
972 CgiDataUtilities::getData(cgiIn,
"targetTableVersion");
973 std::string targetUID = CgiDataUtilities::getData(cgiIn,
"targetUID");
974 std::string targetColumn = CgiDataUtilities::getData(cgiIn,
"targetColumn");
975 std::string newValue = CgiDataUtilities::postData(cgiIn,
"newValue");
977 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
978 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
979 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
980 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
981 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
982 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
984 handleSaveTreeNodeEditXML(xmlOut,
987 TableVersion(targetTableVersion),
989 CgiDataUtilities::decodeURIComponent(targetUID),
990 CgiDataUtilities::decodeURIComponent(targetColumn),
994 else if(requestType ==
"getLinkToChoices")
996 std::string linkToTableName = CgiDataUtilities::getData(cgiIn,
"linkToTableName");
997 std::string linkToTableVersion =
998 CgiDataUtilities::getData(cgiIn,
"linkToTableVersion");
999 std::string linkIdType = CgiDataUtilities::getData(cgiIn,
"linkIdType");
1000 std::string linkIndex = CgiDataUtilities::decodeURIComponent(
1001 CgiDataUtilities::getData(cgiIn,
"linkIndex"));
1002 std::string linkInitId = CgiDataUtilities::getData(cgiIn,
"linkInitId");
1004 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1005 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1006 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1007 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1008 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1010 handleGetLinkToChoicesXML(xmlOut,
1013 TableVersion(linkToTableVersion),
1018 else if(requestType ==
"activateTableGroup")
1020 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1021 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1022 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1024 __SUP_COUT__ <<
"Activating config: " << groupName <<
"(" << groupKey <<
")"
1026 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
1029 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1030 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1031 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1033 std::string accumulatedTreeErrors;
1036 cfgMgr->activateTableGroup(
1038 TableGroupKey(groupKey),
1041 : &accumulatedTreeErrors);
1043 catch(std::runtime_error& e)
1048 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1049 xmlOut.addTextElementToData(
1051 "Error activating config group '" + groupName +
"(" + groupKey +
")" +
1052 ".' Please see details below:\n\n" + std::string(e.what()));
1053 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1054 <<
" (" << groupKey <<
")" << __E__;
1057 cfgMgr->destroyTableGroup(groupName,
true);
1063 catch(cet::exception& e)
1069 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1070 xmlOut.addTextElementToData(
"Error",
1071 "Error activating config group '" + groupName +
1072 "(" + groupKey +
")" +
"!'\n\n" +
1073 std::string(e.what()));
1074 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1075 <<
" (" << groupKey <<
")" << __E__;
1078 cfgMgr->destroyTableGroup(groupName,
true);
1086 __SUP_COUT__ <<
"Error detected!" << __E__;
1090 if(accumulatedTreeErrors !=
"")
1091 xmlOut.addTextElementToData(
"Error",
1092 "Warnings were found when activating group '" +
1093 groupName +
"(" + groupKey +
")" +
1094 "'! Please see details below:\n\n" +
1095 accumulatedTreeErrors);
1097 else if(requestType ==
"getActiveTableGroups")
1099 else if(requestType ==
"copyViewToCurrentColumns")
1101 std::string tableName =
1102 CgiDataUtilities::getData(cgiIn,
"tableName");
1103 std::string sourceVersion = CgiDataUtilities::getData(cgiIn,
"sourceVersion");
1105 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1106 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1107 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1110 TableVersion newTemporaryVersion;
1114 newTemporaryVersion =
1115 cfgMgr->copyViewToCurrentColumns(tableName, TableVersion(sourceVersion));
1128 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1130 catch(std::runtime_error& e)
1132 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1133 xmlOut.addTextElementToData(
"Error",
1134 "Error copying view from '" + tableName +
"_v" +
1135 sourceVersion +
"'! " +
1136 std::string(e.what()));
1140 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1141 xmlOut.addTextElementToData(
1143 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1146 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1148 else if(requestType ==
"getLastTableGroups")
1150 XDAQ_CONST_CALL xdaq::ApplicationDescriptor* gatewaySupervisor =
1151 allSupervisorInfo_.isWizardMode() ? allSupervisorInfo_.getWizardDescriptor()
1152 : allSupervisorInfo_.getGatewayDescriptor();
1154 std::string timeString;
1155 std::pair<std::string , TableGroupKey> theGroup =
1156 theRemoteWebUsers_.getLastConfigGroup(
1157 gatewaySupervisor,
"Configured", timeString);
1158 xmlOut.addTextElementToData(
"LastConfiguredGroupName", theGroup.first);
1159 xmlOut.addTextElementToData(
"LastConfiguredGroupKey", theGroup.second.toString());
1160 xmlOut.addTextElementToData(
"LastConfiguredGroupTime", timeString);
1161 theGroup = theRemoteWebUsers_.getLastConfigGroup(
1162 gatewaySupervisor,
"Started", timeString);
1163 xmlOut.addTextElementToData(
"LastStartedGroupName", theGroup.first);
1164 xmlOut.addTextElementToData(
"LastStartedGroupKey", theGroup.second.toString());
1165 xmlOut.addTextElementToData(
"LastStartedGroupTime", timeString);
1167 else if(requestType ==
"savePlanCommandSequence")
1169 std::string planName = CgiDataUtilities::getData(cgiIn,
"planName");
1170 std::string commands = CgiDataUtilities::postData(cgiIn,
"commands");
1172 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1173 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1174 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1176 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1177 __SUP_COUT__ <<
"planName: " << planName << __E__;
1178 __SUP_COUT__ <<
"commands: " << commands << __E__;
1179 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1180 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1182 handleSavePlanCommandSequenceXML(xmlOut,
1185 TableGroupKey(groupKey),
1191 else if(requestType ==
"mergeGroups")
1193 std::string groupANameContext =
1194 CgiDataUtilities::getData(cgiIn,
"groupANameContext");
1195 std::string groupAKeyContext =
1196 CgiDataUtilities::getData(cgiIn,
"groupAKeyContext");
1197 std::string groupBNameContext =
1198 CgiDataUtilities::getData(cgiIn,
"groupBNameContext");
1199 std::string groupBKeyContext =
1200 CgiDataUtilities::getData(cgiIn,
"groupBKeyContext");
1201 std::string groupANameConfig =
1202 CgiDataUtilities::getData(cgiIn,
"groupANameConfig");
1203 std::string groupAKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupAKeyConfig");
1204 std::string groupBNameConfig =
1205 CgiDataUtilities::getData(cgiIn,
"groupBNameConfig");
1206 std::string groupBKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupBKeyConfig");
1207 std::string mergeApproach = CgiDataUtilities::getData(cgiIn,
"mergeApproach");
1209 __SUP_COUTV__(groupANameContext);
1210 __SUP_COUTV__(groupAKeyContext);
1211 __SUP_COUTV__(groupBNameContext);
1212 __SUP_COUTV__(groupBKeyContext);
1213 __SUP_COUTV__(groupANameConfig);
1214 __SUP_COUTV__(groupAKeyConfig);
1215 __SUP_COUTV__(groupBNameConfig);
1216 __SUP_COUTV__(groupBKeyConfig);
1217 __SUP_COUTV__(mergeApproach);
1219 handleMergeGroupsXML(xmlOut,
1222 TableGroupKey(groupAKeyContext),
1224 TableGroupKey(groupBKeyContext),
1226 TableGroupKey(groupAKeyConfig),
1228 TableGroupKey(groupBKeyConfig),
1234 __SUP_SS__ <<
"requestType '" << requestType <<
"' request not recognized."
1236 __SUP_COUT__ <<
"\n" << ss.str();
1237 xmlOut.addTextElementToData(
"Error", ss.str());
1243 std::map<std::string , std::pair<std::string , TableGroupKey>>
1244 activeGroupMap = cfgMgr->getActiveTableGroups();
1246 for(
auto& type : activeGroupMap)
1248 xmlOut.addTextElementToData(type.first +
"-ActiveGroupName", type.second.first);
1249 xmlOut.addTextElementToData(type.first +
"-ActiveGroupKey",
1250 type.second.second.toString());
1256 xmlOut.addTextElementToData(
1258 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1265 catch(
const std::runtime_error& e)
1267 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1268 <<
".' Error: " << e.what() << __E__;
1269 __COUT_ERR__ <<
"\n" << ss.str();
1270 xmlOut.addTextElementToData(
"Error", ss.str());
1275 xmlOut.addTextElementToData(
1277 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1281 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1286 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1287 << requestType <<
".'" << __E__;
1288 __COUT_ERR__ <<
"\n" << ss.str();
1289 xmlOut.addTextElementToData(
"Error", ss.str());
1294 xmlOut.addTextElementToData(
1296 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1300 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1312 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1313 HttpXmlDocument& xmlOut,
1314 ConfigurationManagerRW* cfgMgr,
1315 const std::string& rootGroupName,
1316 const TableGroupKey& rootGroupKey,
1317 const std::string& modifiedTables)
try
1327 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1328 cfgMgr->getActiveTableGroups();
1332 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT]
1333 .second.isInvalid())
1335 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1336 if(cfgMgr->getFailedTableGroups().find(
1337 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT) !=
1338 cfgMgr->getFailedTableGroups().end())
1340 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1341 cfgMgr->getFailedTableGroups().at(
1342 ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT);
1344 else if(cfgMgr->getFailedTableGroups().find(
1345 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1346 cfgMgr->getFailedTableGroups().end())
1348 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONTEXT] =
1349 cfgMgr->getFailedTableGroups().at(
1350 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1353 if(consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION]
1354 .second.isInvalid())
1356 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1357 if(cfgMgr->getFailedTableGroups().find(
1358 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION) !=
1359 cfgMgr->getFailedTableGroups().end())
1361 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1362 cfgMgr->getFailedTableGroups().at(
1363 ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION);
1365 else if(cfgMgr->getFailedTableGroups().find(
1366 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN) !=
1367 cfgMgr->getFailedTableGroups().end())
1369 consideredGroups[ConfigurationManager::ACTIVE_GROUP_NAME_CONFIGURATION] =
1370 cfgMgr->getFailedTableGroups().at(
1371 ConfigurationManager::ACTIVE_GROUP_NAME_UNKNOWN);
1375 __SUP_COUTV__(StringMacros::mapToString(consideredGroups));
1380 std::map<std::string , TableVersion > rootGroupMemberMap;
1382 cfgMgr->loadTableGroup(rootGroupName,
1385 &rootGroupMemberMap,
1393 const std::string& groupType = cfgMgr->getTypeNameOfGroup(rootGroupMemberMap);
1395 consideredGroups[groupType] =
1396 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1398 catch(
const std::runtime_error& e)
1401 if(rootGroupName.size())
1403 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1404 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1405 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1410 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1411 "name - assuming this was intentional."
1417 if(rootGroupName.size())
1419 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1420 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1425 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1426 "name - assuming this was intentional."
1430 std::map<std::string , TableVersion > modifiedTablesMap;
1431 std::map<std::string , TableVersion >::iterator
1432 modifiedTablesMapIt;
1434 std::istringstream f(modifiedTables);
1435 std::string table, version;
1436 while(getline(f, table,
','))
1438 getline(f, version,
',');
1439 modifiedTablesMap.insert(
1440 std::pair<std::string /*name*/, TableVersion /*version*/>(
1441 table, TableVersion(version)));
1443 __SUP_COUT__ << modifiedTables << __E__;
1444 for(
auto& pair : modifiedTablesMap)
1445 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1450 DOMElement* parentEl;
1451 std::string groupComment;
1452 for(
auto group : consideredGroups)
1454 if(group.second.second.isInvalid())
1457 __SUP_COUT__ <<
"Considering " << group.first <<
" group " << group.second.first
1458 <<
" (" << group.second.second <<
")" << __E__;
1462 std::map<std::string , TableVersion > memberMap;
1463 cfgMgr->loadTableGroup(group.second.first,
1464 group.second.second,
1474 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1476 for(
auto& table : memberMap)
1478 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1481 table.second != (*modifiedTablesMapIt).second)
1483 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1484 << (*modifiedTablesMapIt).second << __E__;
1486 memberMap[table.first] = (*modifiedTablesMapIt).second;
1492 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1493 xmlOut.addTextElementToParent(
"GroupName", group.second.first, parentEl);
1494 xmlOut.addTextElementToParent(
1495 "GroupKey", group.second.second.toString(), parentEl);
1496 xmlOut.addTextElementToParent(
"GroupComment", groupComment, parentEl);
1498 for(
auto& table : memberMap)
1500 xmlOut.addTextElementToParent(
"MemberName", table.first, parentEl);
1501 xmlOut.addTextElementToParent(
1502 "MemberVersion", table.second.toString(), parentEl);
1507 catch(std::runtime_error& e)
1509 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1510 xmlOut.addTextElementToData(
1511 "Error",
"Error getting affected groups! " + std::string(e.what()));
1515 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1516 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1527 void ConfigurationGUISupervisor::setupActiveTablesXML(
1528 HttpXmlDocument& xmlOut,
1529 ConfigurationManagerRW* cfgMgr,
1530 const std::string& groupName,
1531 const TableGroupKey& groupKey,
1532 const std::string& modifiedTables,
1534 bool doGetGroupInfo,
1535 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1536 bool outputActiveTables,
1537 std::string* accumulatedErrors)
try
1542 xmlOut.addTextElementToData(
"configGroup", groupName);
1543 xmlOut.addTextElementToData(
"configGroupKey", groupKey.toString());
1545 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
1548 if(usingActiveGroups || refreshAll)
1550 __SUP_COUT__ <<
"Refreshing all table info..." << __E__;
1551 cfgMgr->getAllTableInfo(
true, accumulatedErrors);
1553 if(accumulatedErrors && *accumulatedErrors !=
"")
1554 __SUP_COUTV__(*accumulatedErrors);
1557 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
false);
1559 std::map<std::string , TableVersion > modifiedTablesMap;
1560 std::map<std::string , TableVersion >::iterator
1561 modifiedTablesMapIt;
1563 if(usingActiveGroups)
1566 __SUP_COUT__ <<
"Using active groups." << __E__;
1570 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
1573 std::string groupComment, groupAuthor, configGroupCreationTime;
1576 cfgMgr->loadTableGroup(groupName,
1582 doGetGroupInfo ? &groupComment : 0,
1583 doGetGroupInfo ? &groupAuthor : 0,
1584 doGetGroupInfo ? &configGroupCreationTime : 0);
1588 xmlOut.addTextElementToData(
"configGroupComment", groupComment);
1589 xmlOut.addTextElementToData(
"configGroupAuthor", groupAuthor);
1590 xmlOut.addTextElementToData(
"configGroupCreationTime",
1591 configGroupCreationTime);
1594 if(accumulatedErrors && *accumulatedErrors !=
"")
1595 __SUP_COUTV__(*accumulatedErrors);
1600 std::istringstream f(modifiedTables);
1601 std::string table, version;
1602 while(getline(f, table,
','))
1604 getline(f, version,
',');
1605 modifiedTablesMap.insert(
1606 std::pair<std::string /*name*/, TableVersion /*version*/>(
1607 table, TableVersion(version)));
1610 for(
auto& pair : modifiedTablesMap)
1611 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1616 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
1617 xmlOut.addTextElementToData(
"DefaultNoLink",
1618 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
1619 for(
auto& activePair : allActivePairs)
1621 if(outputActiveTables)
1622 xmlOut.addTextElementToData(
"ActiveTableName", activePair.first);
1626 if((modifiedTablesMapIt = modifiedTablesMap.find(activePair.first)) !=
1627 modifiedTablesMap.end())
1629 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
1630 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
1634 allTableInfo.at(activePair.first)
1635 .tablePtr_->setActiveView((*modifiedTablesMapIt).second);
1640 <<
"Modified table version v" << (*modifiedTablesMapIt).second
1641 <<
" failed. Reverting to v"
1642 << allTableInfo.at(activePair.first).tablePtr_->getView().getVersion()
1644 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
1645 xmlOut.addTextElementToData(
1647 "Error setting up active tables!\n\n" + std::string(ss.str()));
1651 if(outputActiveTables)
1653 xmlOut.addTextElementToData(
"ActiveTableVersion",
1654 allTableInfo.at(activePair.first)
1655 .tablePtr_->getView()
1658 xmlOut.addTextElementToData(
1659 "ActiveTableComment",
1660 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
1669 catch(std::runtime_error& e)
1671 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
1673 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1674 xmlOut.addTextElementToData(
"Error", ss.str());
1678 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
1679 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1680 xmlOut.addTextElementToData(
"Error", ss.str());
1698 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
1699 HttpXmlDocument& xmlOut,
1700 ConfigurationManagerRW* cfgMgr,
1701 const std::string& groupName,
1702 const TableGroupKey& groupKey,
1703 const std::string& startPath,
1704 const std::string& modifiedTables,
1705 const std::string& recordList,
1706 const std::string& author)
1709 setupActiveTablesXML(xmlOut,
1721 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
1722 TableBase* config = cfgMgr->getTableByName(targetNode.getTableName());
1724 __SUP_COUT__ << config->getTableName() << __E__;
1725 TableVersion temporaryVersion;
1734 bool firstSave =
true;
1737 TableView backupView;
1741 std::istringstream f(recordList);
1742 std::string recordUID;
1745 while(getline(f, recordUID,
','))
1747 recordUID = StringMacros::decodeURIComponent(recordUID);
1749 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
1753 if(!(temporaryVersion = targetNode.getTableVersion())
1754 .isTemporaryVersion())
1756 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
1758 temporaryVersion = config->createTemporaryView(temporaryVersion);
1759 cfgMgr->saveNewTable(targetNode.getTableName(),
1764 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
1768 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
1774 backupView.copy(config->getView(), temporaryVersion, author);
1783 unsigned int row = config->getViewP()->addRow(
1790 unsigned int col = config->getViewP()->getColStatus();
1791 config->getViewP()->setURIEncodedValue(
"1", row, col);
1798 config->getViewP()->setURIEncodedValue(
1799 recordUID, row, config->getViewP()->getColUID());
1807 config->getViewP()->init();
1811 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
1812 __SUP_COUT__ <<
"Before:" << __E__;
1813 config->getViewP()->print();
1814 config->getViewP()->copy(backupView, temporaryVersion, author);
1815 __SUP_COUT__ <<
"After:" << __E__;
1816 config->getViewP()->print();
1822 handleFillModifiedTablesXML(xmlOut, cfgMgr);
1824 catch(std::runtime_error& e)
1826 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
1828 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1829 xmlOut.addTextElementToData(
"Error", ss.str());
1833 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
1834 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1835 xmlOut.addTextElementToData(
"Error", ss.str());
1842 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
1843 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr)
try
1846 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
1847 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
1848 for(
auto& activePair : allActivePairs)
1850 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
1851 xmlOut.addTextElementToData(
"NewActiveTableVersion",
1852 allTableInfo.at(activePair.first)
1853 .tablePtr_->getView()
1856 xmlOut.addTextElementToData(
1857 "NewActiveTableComment",
1858 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
1861 catch(std::runtime_error& e)
1863 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
1864 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1865 xmlOut.addTextElementToData(
"Error", ss.str());
1869 __SUP_SS__ << (
"Error!\n\n") << __E__;
1870 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1871 xmlOut.addTextElementToData(
"Error", ss.str());
1889 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
1890 HttpXmlDocument& xmlOut,
1891 ConfigurationManagerRW* cfgMgr,
1892 const std::string& groupName,
1893 const TableGroupKey& groupKey,
1894 const std::string& startPath,
1895 const std::string& modifiedTables,
1896 const std::string& recordList)
1899 setupActiveTablesXML(xmlOut,
1911 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
1912 TableBase* config = cfgMgr->getTableByName(targetNode.getTableName());
1914 __SUP_COUT__ << config->getTableName() << __E__;
1915 TableVersion temporaryVersion;
1924 bool firstSave =
true;
1928 std::istringstream f(recordList);
1929 std::string recordUID;
1932 while(getline(f, recordUID,
','))
1934 recordUID = StringMacros::decodeURIComponent(recordUID);
1936 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
1940 if(!(temporaryVersion = targetNode.getTableVersion())
1941 .isTemporaryVersion())
1943 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
1945 temporaryVersion = config->createTemporaryView(temporaryVersion);
1946 cfgMgr->saveNewTable(targetNode.getTableName(),
1951 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
1955 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
1965 unsigned int row = config->getViewP()->findRow(
1966 config->getViewP()->getColUID(), recordUID);
1967 config->getViewP()->deleteRow(row);
1972 config->getViewP()->init();
1974 handleFillModifiedTablesXML(xmlOut, cfgMgr);
1976 catch(std::runtime_error& e)
1978 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
1979 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1980 xmlOut.addTextElementToData(
"Error", ss.str());
1984 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
1985 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1986 xmlOut.addTextElementToData(
"Error", ss.str());
2007 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2008 HttpXmlDocument& xmlOut,
2009 ConfigurationManagerRW* cfgMgr,
2010 const std::string& groupName,
2011 const TableGroupKey& groupKey,
2012 const std::string& startPath,
2013 const std::string& modifiedTables,
2014 const std::string& recordList,
2015 const std::string& fieldList,
2016 const std::string& valueList,
2017 const std::string& author)
2020 setupActiveTablesXML(xmlOut,
2035 std::vector<std::string > fieldPaths;
2038 std::istringstream f(fieldList);
2039 std::string fieldPath;
2040 while(getline(f, fieldPath,
','))
2042 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2044 __SUP_COUT__ << fieldList << __E__;
2045 for(
const auto& field : fieldPaths)
2046 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2049 std::vector<std::string > fieldValues;
2052 std::istringstream f(valueList);
2053 std::string fieldValue;
2054 while(getline(f, fieldValue,
','))
2056 fieldValues.push_back(
2062 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2063 fieldValues.push_back(
"");
2065 __SUP_COUT__ << valueList << __E__;
2066 for(
const auto& value : fieldValues)
2067 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2070 if(fieldPaths.size() != fieldValues.size())
2073 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2079 TableVersion temporaryVersion;
2080 std::istringstream f(recordList);
2081 std::string recordUID;
2084 while(getline(f, recordUID,
','))
2086 recordUID = StringMacros::decodeURIComponent(recordUID);
2090 DOMElement* parentEl =
2091 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2094 for(i = 0; i < fieldPaths.size(); ++i)
2096 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2097 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2101 ConfigurationTree targetNode =
2102 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2137 __SUP_COUT__ <<
"Getting table " << targetNode.getFieldTableName()
2141 config = cfgMgr->getTableByName(
2142 targetNode.getFieldTableName());
2143 if(!(temporaryVersion = config->getViewP()->getVersion())
2144 .isTemporaryVersion())
2148 config->createTemporaryView(config->getViewP()->getVersion());
2149 cfgMgr->saveNewTable(config->getTableName(),
2154 __SUP_COUT__ <<
"Created temporary version "
2155 << config->getTableName() <<
"-v" << temporaryVersion
2159 __SUP_COUT__ <<
"Using temporary version " << config->getTableName()
2160 <<
"-v" << temporaryVersion << __E__;
2164 config->getViewP()->setURIEncodedValue(fieldValues[i],
2165 targetNode.getFieldRow(),
2166 targetNode.getFieldColumn(),
2175 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2177 catch(std::runtime_error& e)
2179 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2181 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2182 xmlOut.addTextElementToData(
"Error", ss.str());
2186 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2187 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2188 xmlOut.addTextElementToData(
"Error", ss.str());
2207 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2208 HttpXmlDocument& xmlOut,
2209 ConfigurationManagerRW* cfgMgr,
2210 const std::string& groupName,
2211 const TableGroupKey& groupKey,
2212 const std::string& startPath,
2213 const std::string& modifiedTables,
2214 const std::string& recordList,
2215 const std::string& fieldList)
2218 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2225 std::vector<std::string > fieldPaths;
2228 std::istringstream f(fieldList);
2229 std::string fieldPath;
2230 while(getline(f, fieldPath,
','))
2232 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2234 __SUP_COUT__ << fieldList << __E__;
2235 for(
auto& field : fieldPaths)
2236 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2241 std::istringstream f(recordList);
2242 std::string recordUID;
2243 while(getline(f, recordUID,
','))
2245 recordUID = StringMacros::decodeURIComponent(recordUID);
2247 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2249 DOMElement* parentEl =
2250 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2253 for(
const auto& fieldPath : fieldPaths)
2255 __SUP_COUT__ <<
"fieldPath " << fieldPath << __E__;
2257 ConfigurationTree node =
2258 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
2260 xmlOut.addTextElementToParent(
"FieldPath", fieldPath, parentEl);
2262 xmlOut.addTextElementToParent(
2264 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath)
2265 .getValueAsString(
true ),
2271 catch(std::runtime_error& e)
2273 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
2275 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2276 xmlOut.addTextElementToData(
"Error", ss.str());
2280 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
2281 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2282 xmlOut.addTextElementToData(
"Error", ss.str());
2305 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
2306 HttpXmlDocument& xmlOut,
2307 ConfigurationManagerRW* cfgMgr,
2308 const std::string& groupName,
2309 const TableGroupKey& groupKey,
2310 const std::string& startPath,
2312 const std::string& modifiedTables,
2313 const std::string& recordList,
2314 const std::string& fieldList)
2317 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2321 DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
2325 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
2326 __SUP_COUT__ << ss.str();
2335 std::vector<ConfigurationTree::RecordField> retFieldList;
2338 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2339 if(startNode.isLinkNode() && startNode.isDisconnected())
2341 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
2342 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2348 std::vector<std::string > fieldAcceptList, fieldRejectList;
2353 std::istringstream f(fieldList);
2354 std::string fieldPath, decodedFieldPath;
2355 while(getline(f, fieldPath,
','))
2357 decodedFieldPath = StringMacros::decodeURIComponent(fieldPath);
2359 if(decodedFieldPath[0] ==
'!')
2360 fieldRejectList.push_back(decodedFieldPath.substr(1));
2362 fieldAcceptList.push_back(decodedFieldPath);
2364 __SUP_COUT__ << fieldList << __E__;
2365 for(
auto& field : fieldAcceptList)
2366 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
2367 for(
auto& field : fieldRejectList)
2368 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
2372 std::vector<std::string > records;
2373 if(recordList ==
"*")
2376 records = startNode.getChildrenNames();
2377 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2378 for(
auto& record : records)
2379 __SUP_COUT__ <<
"recordList " << record << __E__;
2381 else if(recordList !=
"")
2385 std::istringstream f(recordList);
2386 std::string recordStr;
2387 while(getline(f, recordStr,
','))
2389 records.push_back(StringMacros::decodeURIComponent(recordStr));
2391 __SUP_COUT__ << recordList << __E__;
2392 for(
auto& record : records)
2393 __SUP_COUT__ <<
"recordList " << record << __E__;
2397 retFieldList = startNode.getCommonFields(
2398 records, fieldAcceptList, fieldRejectList, depth);
2401 DOMElement* parentTypeEl;
2402 for(
const auto& fieldInfo : retFieldList)
2404 xmlOut.addTextElementToParent(
2405 "FieldTableName", fieldInfo.tableName_, parentEl);
2406 xmlOut.addTextElementToParent(
2407 "FieldColumnName", fieldInfo.columnName_, parentEl);
2408 xmlOut.addTextElementToParent(
2409 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
2410 xmlOut.addTextElementToParent(
2411 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
2412 xmlOut.addTextElementToParent(
2413 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
2414 xmlOut.addTextElementToParent(
"FieldColumnDefaultValue",
2415 fieldInfo.columnInfo_->getDefaultValue(),
2419 xmlOut.addTextElementToParent(
"FieldColumnDataChoices",
"", parentEl);
2422 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
2423 xmlOut.addTextElementToParent(
2424 "FieldColumnDataChoice",
2425 fieldInfo.columnInfo_->getDefaultValue(),
2427 for(
const auto& dataChoice : dataChoices)
2428 xmlOut.addTextElementToParent(
2429 "FieldColumnDataChoice", dataChoice, parentTypeEl);
2432 catch(std::runtime_error& e)
2434 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
2436 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2437 xmlOut.addTextElementToData(
"Error", ss.str());
2441 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
2442 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2443 xmlOut.addTextElementToData(
"Error", ss.str());
2475 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
2476 HttpXmlDocument& xmlOut,
2477 ConfigurationManagerRW* cfgMgr,
2478 const std::string& groupName,
2479 const TableGroupKey& groupKey,
2480 const std::string& startPath,
2481 const std::string& modifiedTables,
2482 const std::string& recordList,
2483 const std::string& fieldList)
2486 setupActiveTablesXML(xmlOut, cfgMgr, groupName, groupKey, modifiedTables);
2492 if(startPath ==
"/")
2495 ConfigurationTree startNode = cfgMgr->getNode(startPath);
2496 if(startNode.isLinkNode() && startNode.isDisconnected())
2498 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
2499 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2504 std::vector<std::string > records;
2505 if(recordList ==
"*")
2508 records = startNode.getChildrenNames();
2509 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
2510 for(
auto& record : records)
2511 __SUP_COUT__ <<
"recordList " << record << __E__;
2513 else if(recordList !=
"")
2517 std::istringstream f(recordList);
2518 std::string recordStr;
2519 while(getline(f, recordStr,
','))
2521 records.push_back(StringMacros::decodeURIComponent(recordStr));
2523 __SUP_COUT__ << recordList << __E__;
2524 for(
auto& record : records)
2525 __SUP_COUT__ <<
"recordList " << record << __E__;
2530 std::vector<std::string > fieldsToGet;
2535 if(fieldList ==
"AUTO")
2540 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
2542 std::vector<ConfigurationTree::RecordField> retFieldList;
2543 std::vector<std::string > fieldAcceptList,
2545 fieldRejectList.push_back(
"*CommentDescription");
2546 retFieldList = startNode.getCommonFields(
2547 records, fieldAcceptList, fieldRejectList, 5,
true );
2549 for(
const auto& retField : retFieldList)
2550 fieldsToGet.push_back(retField.columnName_);
2554 std::istringstream f(fieldList);
2555 std::string fieldPath;
2556 while(getline(f, fieldPath,
','))
2558 fieldsToGet.push_back(StringMacros::decodeURIComponent(fieldPath));
2560 __SUP_COUTV__(fieldList);
2564 __SUP_COUTV__(StringMacros::vectorToString(fieldsToGet));
2567 for(
auto& field : fieldsToGet)
2569 __SUP_COUTV__(field);
2571 DOMElement* parentEl = xmlOut.addTextElementToData(
"field", field);
2574 std::set<std::string > uniqueValues;
2577 cfgMgr->getNode(startPath).getUniqueValuesForField(records, field);
2579 for(
auto& uniqueValue : uniqueValues)
2581 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
2583 xmlOut.addTextElementToParent(
"uniqueValue", uniqueValue, parentEl);
2587 catch(std::runtime_error& e)
2589 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
2591 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2592 xmlOut.addTextElementToData(
"Error", ss.str());
2596 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
2597 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2598 xmlOut.addTextElementToData(
"Error", ss.str());
2622 void ConfigurationGUISupervisor::handleFillTreeViewXML(HttpXmlDocument& xmlOut,
2623 ConfigurationManagerRW* cfgMgr,
2624 const std::string& groupName,
2625 const TableGroupKey& groupKey,
2626 const std::string& startPath,
2628 bool hideStatusFalse,
2629 const std::string& modifiedTables,
2630 const std::string& filterList)
2661 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
2662 std::map<std::string , TableVersion > memberMap;
2664 std::string accumulatedErrors =
"";
2667 setupActiveTablesXML(
2682 catch(
const std::runtime_error& e)
2684 __SS__ <<
"Error occured setting up active tables: " << e.what() << __E__;
2685 accumulatedErrors += ss.str();
2689 __SS__ <<
"Unknown error occured setting up active tables." << __E__;
2690 accumulatedErrors += ss.str();
2693 if(accumulatedErrors !=
"")
2695 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
2697 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
2701 __SUP_COUT__ <<
"Active tables are setup. No issues found." << __E__;
2705 DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
2710 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
2712 if(startPath ==
"/")
2716 std::string accumulateTreeErrs;
2718 if(usingActiveGroups)
2719 rootMap = cfgMgr->getChildren(0, &accumulateTreeErrs);
2721 rootMap = cfgMgr->getChildren(&memberMap, &accumulateTreeErrs);
2723 __SUP_COUT__ <<
"accumulateTreeErrs = " << accumulateTreeErrs << __E__;
2724 if(accumulateTreeErrs !=
"")
2725 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
2729 ConfigurationTree startNode =
2730 cfgMgr->getNode(startPath,
true );
2731 if(startNode.isLinkNode() && startNode.isDisconnected())
2733 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
2738 std::map<std::string , std::string > filterMap;
2739 StringMacros::getMapFromString(
2742 std::set<char>({
';'}) ,
2743 std::set<char>({
'='}) );
2745 __COUTV__(StringMacros::mapToString(filterMap));
2747 rootMap = cfgMgr->getNode(startPath).getChildren(filterMap);
2750 for(
auto& treePair : rootMap)
2752 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
2754 catch(std::runtime_error& e)
2756 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
2757 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2758 xmlOut.addTextElementToData(
"Error", ss.str());
2762 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
2763 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2764 xmlOut.addTextElementToData(
"Error", ss.str());
2774 void ConfigurationGUISupervisor::recursiveTreeToXML(
const ConfigurationTree& t,
2776 HttpXmlDocument& xmlOut,
2777 DOMElement* parentEl,
2778 bool hideStatusFalse)
2784 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2785 xmlOut.addTextElementToParent(
"value", t.getValueAsString(), parentEl);
2786 parentEl = xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2790 if(t.getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
2791 t.getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
2795 std::vector<std::string> choices = t.getFixedChoices();
2796 for(
const auto& choice : choices)
2797 xmlOut.addTextElementToParent(
"fixedChoice", choice, parentEl);
2808 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
2810 if(t.isDisconnected())
2812 __COUT__ << t.getValueName() << __E__;
2818 xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
2821 xmlOut.addTextElementToParent(
2822 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
2823 t.getDisconnectedLinkID(),
2825 xmlOut.addTextElementToParent(
2826 "LinkTableName", t.getDisconnectedTableName(), parentEl);
2827 xmlOut.addTextElementToParent(
2828 "LinkIndex", t.getChildLinkIndex(), parentEl);
2831 DOMElement* choicesParentEl =
2832 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
2836 std::vector<std::string> choices = t.getFixedChoices();
2837 __COUT__ <<
"choices.size() " << choices.size() << __E__;
2839 for(
const auto& choice : choices)
2840 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2852 xmlOut.addTextElementToParent(
2853 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
2854 t.getValueAsString(),
2857 xmlOut.addTextElementToParent(
"LinkTableName", t.getTableName(), parentEl);
2859 xmlOut.addTextElementToParent(
"LinkIndex", t.getChildLinkIndex(), parentEl);
2863 DOMElement* choicesParentEl =
2864 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
2865 std::vector<std::string> choices = t.getFixedChoices();
2869 for(
const auto& choice : choices)
2870 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
2875 bool returnNode =
true;
2881 t.getNode(TableViewColumnInfo::COL_NAME_STATUS).getValue(returnNode);
2890 xmlOut.addTextElementToParent(
"node", t.getValueAsString(), parentEl);
2899 auto C = t.getChildren();
2902 c.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
2914 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
2915 HttpXmlDocument& xmlOut,
2916 ConfigurationManagerRW* cfgMgr,
2917 const std::string& linkToTableName,
2918 const TableVersion& linkToTableVersion,
2919 const std::string& linkIdType,
2920 const std::string& linkIndex,
2921 const std::string& linkInitId)
try
2933 const std::string& tableName = linkToTableName;
2934 const TableVersion& version = linkToTableVersion;
2935 TableBase* config = cfgMgr->getTableByName(tableName);
2938 config->setActiveView(version);
2942 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
2943 << version << __E__;
2944 cfgMgr->getVersionedTableByName(tableName, version);
2947 if(version != config->getViewVersion())
2949 __SUP_SS__ <<
"Target table version (" << version
2950 <<
") is not the currently active version ("
2951 << config->getViewVersion() <<
". Try refreshing the tree." << __E__;
2952 __SUP_COUT_WARN__ << ss.str();
2956 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
2958 if(linkIdType ==
"UID")
2961 unsigned int col = config->getView().getColUID();
2962 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
2963 xmlOut.addTextElementToData(
"linkToChoice",
2964 config->getView().getDataView()[row][col]);
2966 else if(linkIdType ==
"GroupID")
2972 __SUP_COUTV__(linkIndex);
2973 __SUP_COUTV__(linkInitId);
2975 std::set<std::string> setOfGroupIDs =
2976 config->getView().getSetOfGroupIDs(linkIndex);
2981 bool foundInitId =
false;
2982 for(
const auto& groupID : setOfGroupIDs)
2984 if(!foundInitId && linkInitId == groupID)
2987 xmlOut.addTextElementToData(
"linkToChoice", groupID);
2991 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
2994 unsigned int col = config->getView().getColUID();
2995 for(
unsigned int row = 0; row < config->getView().getNumberOfRows(); ++row)
2997 xmlOut.addTextElementToData(
"groupChoice",
2998 config->getView().getDataView()[row][col]);
2999 if(config->getView().isEntryInGroup(row, linkIndex, linkInitId))
3000 xmlOut.addTextElementToData(
"groupMember",
3001 config->getView().getDataView()[row][col]);
3006 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
3010 catch(std::runtime_error& e)
3012 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
3013 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3014 xmlOut.addTextElementToData(
"Error", ss.str());
3018 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
3019 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3020 xmlOut.addTextElementToData(
"Error", ss.str());
3025 void ConfigurationGUISupervisor::handleMergeGroupsXML(
3026 HttpXmlDocument& xmlOut,
3027 ConfigurationManagerRW* cfgMgr,
3028 const std::string& groupANameContext,
3029 const TableGroupKey& groupAKeyContext,
3030 const std::string& groupBNameContext,
3031 const TableGroupKey& groupBKeyContext,
3032 const std::string& groupANameConfig,
3033 const TableGroupKey& groupAKeyConfig,
3034 const std::string& groupBNameConfig,
3035 const TableGroupKey& groupBKeyConfig,
3036 const std::string& author,
3037 const std::string& mergeApproach)
try
3039 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
3040 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3041 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3042 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3043 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
3059 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
3060 mergeApproach ==
"Skip"))
3062 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
3066 std::map<std::string , TableVersion > memberMapAContext,
3067 memberMapBContext, memberMapAConfig, memberMapBConfig;
3070 bool skippingContextPair =
false;
3071 bool skippingConfigPair =
false;
3072 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
3073 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
3075 skippingContextPair =
true;
3076 __SUP_COUTV__(skippingContextPair);
3078 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
3079 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
3081 skippingConfigPair =
true;
3082 __SUP_COUTV__(skippingConfigPair);
3086 if(!skippingContextPair)
3088 cfgMgr->loadTableGroup(groupANameContext,
3100 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
3102 cfgMgr->loadTableGroup(groupBNameContext,
3115 __SUP_COUTV__(StringMacros::mapToString(memberMapBContext));
3119 if(!skippingConfigPair)
3121 cfgMgr->loadTableGroup(groupANameConfig,
3133 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
3135 cfgMgr->loadTableGroup(groupBNameConfig,
3148 __SUP_COUTV__(StringMacros::mapToString(memberMapBConfig));
3156 std::map<std::pair<std::string , std::string >,
3160 std::pair<std::string ,
3161 std::pair<std::string , std::string >>,
3163 groupidConversionMap;
3167 for(
unsigned int i = 0; i < 2; ++i)
3169 if(i == 0 && mergeApproach !=
"Rename")
3173 for(
unsigned int j = 0; j < 2; ++j)
3175 if(j == 0 && skippingContextPair)
3177 __COUT__ <<
"Skipping context pair..." << __E__;
3180 else if(j == 1 && skippingConfigPair)
3182 __COUT__ <<
"Skipping config pair..." << __E__;
3186 std::map<std::string , TableVersion >& memberMapAref =
3187 j == 0 ? memberMapAContext : memberMapAConfig;
3189 std::map<std::string , TableVersion >& memberMapBref =
3190 j == 0 ? memberMapBContext : memberMapBConfig;
3193 __COUT__ <<
"Context pair..." << __E__;
3195 __COUT__ <<
"Config pair..." << __E__;
3197 __COUT__ <<
"Starting member map B scan." << __E__;
3198 for(
const auto bkey : memberMapBref)
3200 __SUP_COUTV__(bkey.first);
3202 if(memberMapAref.find(bkey.first) == memberMapAref.end())
3205 memberMapAref[bkey.first] = bkey.second;
3207 else if(memberMapAref[bkey.first] != bkey.second)
3210 __SUP_COUTV__(memberMapAref[bkey.first]);
3211 __SUP_COUTV__(bkey.second);
3214 TableBase* config = cfgMgr->getTableByName(bkey.first);
3216 __SUP_COUT__ <<
"Got table." << __E__;
3218 TableVersion newVersion = config->mergeViews(
3220 ->getVersionedTableByName(bkey.first,
3221 memberMapAref[bkey.first])
3223 cfgMgr->getVersionedTableByName(bkey.first, bkey.second)
3229 groupidConversionMap,
3232 config->getTableName() ==
3233 ConfigurationManager::
3234 XDAQ_APPLICATION_TABLE_NAME
3240 __SUP_COUTV__(newVersion);
3246 newVersion = saveModifiedVersionXML(
3257 catch(std::runtime_error& e)
3260 <<
"There was an error saving the '"
3261 << config->getTableName()
3262 <<
"' merge result to a persistent table version. "
3263 <<
"Perhaps you can modify this table in one of the "
3264 "groups to resolve this issue, and then re-merge."
3265 << __E__ << e.what();
3269 __SUP_COUTV__(newVersion);
3271 memberMapAref[bkey.first] = newVersion;
3280 if(!skippingContextPair)
3282 __SUP_COUT__ <<
"New context member map complete." << __E__;
3283 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
3286 TableGroupKey newKeyContext = cfgMgr->saveNewTableGroup(
3289 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.toString() +
3290 ") and " + groupBNameContext +
" (" + groupBKeyContext.toString() +
").");
3293 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
3294 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.toString());
3296 if(!skippingConfigPair)
3298 __SUP_COUT__ <<
"New config member map complete." << __E__;
3299 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
3302 TableGroupKey newKeyConfig = cfgMgr->saveNewTableGroup(
3305 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.toString() +
3306 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.toString() +
").");
3309 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
3310 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.toString());
3314 catch(std::runtime_error& e)
3316 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
3317 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3318 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3319 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3320 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
3321 << e.what() << __E__;
3322 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3323 xmlOut.addTextElementToData(
"Error", ss.str());
3327 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
3328 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
3329 << groupBKeyContext <<
") and config group pair " << groupANameConfig
3330 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
3331 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
3332 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3333 xmlOut.addTextElementToData(
"Error", ss.str());
3338 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
3339 HttpXmlDocument& xmlOut,
3340 ConfigurationManagerRW* cfgMgr,
3341 const std::string& groupName,
3342 const TableGroupKey& groupKey,
3343 const std::string& modifiedTables,
3344 const std::string& author,
3345 const std::string& planName,
3346 const std::string& commandString)
try
3348 __MOUT__ <<
"handleSavePlanCommandSequenceXML" << __E__;
3351 setupActiveTablesXML(xmlOut,
3361 TableEditStruct planTable(IterateTable::PLAN_TABLE,
3363 TableEditStruct targetTable(IterateTable::TARGET_TABLE,
3367 std::map<std::string, TableEditStruct> commandTypeToCommandTableMap;
3368 for(
const auto& commandPair : IterateTable::commandToTableMap_)
3369 if(commandPair.second !=
"")
3370 commandTypeToCommandTableMap.emplace(std::pair<std::string, TableEditStruct>(
3371 commandPair.first, TableEditStruct(commandPair.second, cfgMgr)));
3387 std::string groupName = planName +
"-Plan";
3388 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
3390 unsigned int groupIdCol =
3391 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
3392 unsigned int cmdTypeCol =
3393 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
3395 unsigned int targetGroupIdCol =
3396 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
3397 unsigned int targetTableCol =
3398 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
3399 unsigned int targetUIDCol =
3400 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
3402 std::string groupLinkIndex =
3403 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
3404 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
3406 std::pair<
unsigned int ,
unsigned int > commandUidLink;
3409 planTable.tableView_->getChildLink(
3410 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
3415 unsigned int cmdRow, cmdCol;
3416 std::string targetGroupName;
3420 std::string targetUID, cmdType;
3422 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
3425 targetUID = planTable.tableView_
3426 ->getDataView()[row][planTable.tableView_->getColUID()];
3427 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
3430 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
3432 __SUP_COUT__ <<
"Removing." << __E__;
3436 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
3437 if(commandTypeToCommandTableMap.find(cmdType) !=
3438 commandTypeToCommandTableMap
3442 commandTypeToCommandTableMap[cmdType].tableView_->findRow(
3443 commandTypeToCommandTableMap[cmdType]
3444 .tableView_->getColUID(),
3445 planTable.tableView_
3446 ->getDataView()[row][commandUidLink.second]);
3454 commandTypeToCommandTableMap[cmdType].tableView_->findCol(
3455 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
3457 commandTypeToCommandTableMap[cmdType]
3458 .tableView_->getDataView()[cmdRow][cmdCol];
3460 for(
unsigned int trow = 0;
3461 trow < targetTable.tableView_->getNumberOfRows();
3465 if(targetTable.tableView_->isEntryInGroup(
3467 commandTypeToCommandTableMap[cmdType]
3468 .tableView_->getColumnInfo(cmdCol)
3469 .getChildLinkIndex(),
3472 __SUP_COUT__ <<
"Removing target." << __E__;
3474 if(targetTable.tableView_->removeRowFromGroup(
3485 __SUP_COUT__ <<
"No targets." << __E__;
3490 commandTypeToCommandTableMap[cmdType].tableView_->deleteRow(
3493 commandTypeToCommandTableMap[cmdType].modified_ =
true;
3497 if(planTable.tableView_->removeRowFromGroup(
3498 row, groupIdCol, groupName,
true ))
3507 std::vector<IterateTable::Command> commands;
3512 std::istringstream f(commandString);
3513 std::string commandSubString, paramSubString, paramValue;
3515 while(getline(f, commandSubString,
';'))
3518 std::istringstream g(commandSubString);
3521 while(getline(g, paramSubString,
','))
3526 if(paramSubString !=
"type")
3528 __SUP_SS__ <<
"Invalid command sequence" << __E__;
3532 commands.push_back(IterateTable::Command());
3534 getline(g, paramValue,
',');
3537 commands.back().type_ = paramValue;
3541 getline(g, paramValue,
',');
3545 commands.back().params_.emplace(
3546 std::pair<std::string ,
3549 StringMacros::decodeURIComponent(paramValue)));
3558 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
3565 unsigned int row, tgtRow;
3566 unsigned int targetIndex;
3567 std::string targetStr, cmdUID;
3569 for(
auto& command : commands)
3571 __SUP_COUT__ <<
"command " << command.type_ << __E__;
3572 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
3576 row = planTable.tableView_->addRow(author,
"planCommand");
3577 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
3580 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
3583 planTable.tableView_->setValueAsString(
3584 "1", row, planTable.tableView_->getColStatus());
3587 if(commandTypeToCommandTableMap.find(command.type_) !=
3588 commandTypeToCommandTableMap.end())
3591 __SUP_COUT__ <<
"table "
3592 << commandTypeToCommandTableMap[command.type_].tableName_
3598 cmdRow = commandTypeToCommandTableMap[command.type_].tableView_->addRow(
3599 author,
true , command.type_ +
"_COMMAND_");
3605 for(
auto& param : command.params_)
3607 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
3610 if(param.first == IterateTable::targetParams_.Tables_)
3612 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
3613 std::istringstream f(param.second);
3616 while(getline(f, targetStr,
'='))
3618 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3619 if(!command.targets_.size() ||
3620 command.targets_.back().table_ !=
"")
3622 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
3625 command.addTarget();
3626 command.targets_.back().table_ = targetStr;
3629 command.targets_[targetIndex++].table_ = targetStr;
3635 if(param.first == IterateTable::targetParams_.UIDs_)
3637 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
3638 std::istringstream f(param.second);
3641 while(getline(f, targetStr,
'='))
3643 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
3644 if(!command.targets_.size() ||
3645 command.targets_.back().UID_ !=
"")
3647 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
3650 command.addTarget();
3651 command.targets_.back().UID_ = targetStr;
3654 command.targets_[targetIndex++].UID_ = targetStr;
3660 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3663 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
3665 commandTypeToCommandTableMap[command.type_]
3666 .tableView_->setURIEncodedValue(param.second, cmdRow, cmdCol);
3670 commandTypeToCommandTableMap[command.type_].tableView_->getDataView()
3671 [cmdRow][commandTypeToCommandTableMap[command.type_]
3672 .tableView_->getColUID()];
3674 if(command.targets_.size())
3678 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
3682 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3683 IterateTable::commandTargetCols_.TargetsLink_);
3684 commandTypeToCommandTableMap[command.type_]
3685 .tableView_->setValueAsString(
3686 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
3689 commandTypeToCommandTableMap[command.type_].tableView_->findCol(
3690 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
3691 commandTypeToCommandTableMap[command.type_]
3692 .tableView_->setValueAsString(
3693 cmdUID +
"_Targets", cmdRow, cmdCol);
3697 for(
const auto& target : command.targets_)
3699 __SUP_COUT__ << target.table_ <<
" " << target.UID_ << __E__;
3702 tgtRow = targetTable.tableView_->addRow(author,
"commandTarget");
3703 targetTable.tableView_->addRowToGroup(
3704 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
3707 targetTable.tableView_->setValueAsString(
3708 target.table_, tgtRow, targetTableCol);
3711 targetTable.tableView_->setValueAsString(
3712 target.UID_, tgtRow, targetUIDCol);
3717 planTable.tableView_->setValueAsString(
3718 commandTypeToCommandTableMap[command.type_].tableName_,
3720 commandUidLink.first);
3721 planTable.tableView_->setValueAsString(
3722 cmdUID, row, commandUidLink.second);
3724 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
3726 commandTypeToCommandTableMap[command.type_].modified_ =
true;
3734 planTable.tableView_->print();
3735 planTable.tableView_->init();
3737 __SUP_COUT__ <<
"requestType tables:" << __E__;
3739 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3741 modifiedConfig.second.tableView_->print();
3742 modifiedConfig.second.tableView_->init();
3745 targetTable.tableView_->print();
3746 targetTable.tableView_->init();
3751 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
3757 if(planTable.createdTemporaryVersion_)
3759 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
3760 << planTable.temporaryVersion_ << __E__;
3762 cfgMgr->eraseTemporaryVersion(planTable.tableName_,
3763 planTable.temporaryVersion_);
3766 if(targetTable.createdTemporaryVersion_)
3768 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
3769 << targetTable.temporaryVersion_ << __E__;
3771 cfgMgr->eraseTemporaryVersion(targetTable.tableName_,
3772 targetTable.temporaryVersion_);
3775 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3777 if(modifiedConfig.second
3778 .createdTemporaryVersion_)
3780 __SUP_COUT__ <<
"Erasing temporary version "
3781 << modifiedConfig.second.tableName_ <<
"-v"
3782 << modifiedConfig.second.temporaryVersion_ << __E__;
3784 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
3785 modifiedConfig.second.temporaryVersion_);
3796 TableVersion finalVersion = saveModifiedVersionXML(
3799 planTable.tableName_,
3800 planTable.originalVersion_,
3803 planTable.temporaryVersion_,
3806 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
3807 << finalVersion << __E__;
3809 finalVersion = saveModifiedVersionXML(
3812 targetTable.tableName_,
3813 targetTable.originalVersion_,
3816 targetTable.temporaryVersion_,
3819 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
3820 << finalVersion << __E__;
3822 for(
auto& modifiedConfig : commandTypeToCommandTableMap)
3824 if(!modifiedConfig.second.modified_)
3826 if(modifiedConfig.second
3827 .createdTemporaryVersion_)
3829 __SUP_COUT__ <<
"Erasing unmodified temporary version "
3830 << modifiedConfig.second.tableName_ <<
"-v"
3831 << modifiedConfig.second.temporaryVersion_ << __E__;
3833 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
3834 modifiedConfig.second.temporaryVersion_);
3839 finalVersion = saveModifiedVersionXML(
3842 modifiedConfig.second.tableName_,
3843 modifiedConfig.second.originalVersion_,
3845 modifiedConfig.second.table_,
3846 modifiedConfig.second.temporaryVersion_,
3849 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
3850 << finalVersion << __E__;
3853 handleFillModifiedTablesXML(xmlOut, cfgMgr);
3855 catch(std::runtime_error& e)
3857 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
3858 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3859 xmlOut.addTextElementToData(
"Error", ss.str());
3863 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
3864 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
3865 xmlOut.addTextElementToData(
"Error", ss.str());
3878 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(HttpXmlDocument& xmlOut,
3879 ConfigurationManagerRW* cfgMgr,
3880 const std::string& tableName,
3881 TableVersion version,
3882 const std::string& type,
3883 const std::string& uid,
3884 const std::string& colName,
3885 const std::string& newValue,
3886 const std::string& author)
try
3888 __SUP_COUT__ <<
"table " << tableName <<
"(" << version <<
")" << __E__;
3895 TableBase* config = cfgMgr->getTableByName(tableName);
3898 config->setActiveView(version);
3902 if(version.isTemporaryVersion())
3905 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
3906 << version << __E__;
3907 cfgMgr->getVersionedTableByName(tableName, version);
3910 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
3912 if(version != config->getViewVersion())
3914 __SUP_SS__ <<
"Target table version (" << version
3915 <<
") is not the currently active version ("
3916 << config->getViewVersion() <<
". Try refreshing the tree." << __E__;
3920 unsigned int col = -1;
3921 if(type ==
"uid" || type ==
"delete-uid")
3922 col = config->getView().getColUID();
3923 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
3924 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
3925 col = config->getView().findCol(colName);
3926 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
3927 type ==
"table-newUIDRow" || type ==
"table-newRow")
3931 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
3936 if(type ==
"table" || type ==
"link-comment")
3939 if(config->getView().isURIEncodedCommentTheSame(newValue))
3941 __SUP_SS__ <<
"Comment '" << newValue
3942 <<
"' is the same as the current comment. No need to save change."
3958 TableVersion temporaryVersion = config->createTemporaryView(version);
3960 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
3962 TableView* cfgView = config->getTemporaryView(temporaryVersion);
3968 if(type ==
"table" || type ==
"link-comment")
3971 cfgView->setURIEncodedComment(newValue);
3973 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
3976 unsigned int row = cfgView->addRow(author,
true );
3981 col = cfgView->getColStatus();
3982 cfgView->setValueAsString(
"1", row, col);
3989 cfgView->setURIEncodedValue(newValue, row, cfgView->getColUID());
3991 else if(type ==
"table-newGroupRow")
3994 unsigned int row = cfgView->addRow(author,
true );
3997 unsigned int csvIndex = newValue.find(
',');
3999 std::string linkIndex = newValue.substr(0, csvIndex);
4000 std::string groupId = newValue.substr(csvIndex + 1);
4003 csvIndex = groupId.find(
',');
4004 std::string newRowUID = groupId.substr(csvIndex + 1);
4005 groupId = groupId.substr(0, csvIndex);
4007 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
4011 cfgView->setURIEncodedValue(newRowUID, row, cfgView->getColUID());
4014 col = cfgView->getColLinkGroupID(linkIndex);
4017 cfgView->setURIEncodedValue(groupId, row, col);
4022 col = cfgView->getColStatus();
4023 cfgView->setValueAsString(
"1", row, col);
4029 else if(type ==
"delete-uid")
4032 unsigned int row = cfgView->findRow(col, uid);
4033 cfgView->deleteRow(row);
4035 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
4036 type ==
"value-bool" || type ==
"value-bitmap")
4038 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
4039 if(!cfgView->setURIEncodedValue(newValue, row, col, author))
4042 __SUP_SS__ <<
"Value '" << newValue
4043 <<
"' is the same as the current value. No need to save "
4044 "change to tree node."
4049 else if(type ==
"link-UID" || type ==
"link-GroupID")
4052 std::pair<
unsigned int ,
unsigned int > linkPair;
4053 if(!cfgView->getChildLink(col, isGroup, linkPair))
4056 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
4060 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
4063 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
4065 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
4068 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
4070 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
4071 csvIndexStart = csvIndex + 1;
4072 csvIndex = newValue.find(
',', csvIndexStart);
4073 std::string newLinkId = newValue.substr(
4078 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
4081 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
4082 bool changed =
false;
4083 if(!cfgView->setURIEncodedValue(newTable, row, linkPair.first, author))
4086 __SUP_COUT__ <<
"Value '" << newTable
4087 <<
"' is the same as the current value." << __E__;
4092 if(!cfgView->setURIEncodedValue(newLinkId, row, linkPair.second, author))
4095 __SUP_COUT__ <<
"Value '" << newLinkId
4096 <<
"' is the same as the current value." << __E__;
4104 if(type ==
"link-GroupID")
4106 bool secondaryChanged =
false;
4111 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
4113 config->eraseView(temporaryVersion);
4121 saveModifiedVersionXML(xmlOut,
4133 catch(std::runtime_error&
4136 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
4137 "temporary version."
4139 config->eraseView(temporaryVersion);
4143 xmlOut.addTextElementToData(
4145 "Error saving primary tree node! " + std::string(e.what()));
4155 csvIndexStart = csvIndex + 1;
4156 csvIndex = newValue.find(
',', csvIndexStart);
4157 version = TableVersion(newValue.substr(
4158 csvIndexStart, csvIndex - csvIndexStart));
4161 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
4169 config = cfgMgr->getTableByName(newTable);
4172 config->setActiveView(version);
4176 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
4178 << version << __E__;
4179 cfgMgr->getVersionedTableByName(newTable, version);
4182 __SUP_COUT__ <<
"Active version is " << config->getViewVersion() << __E__;
4184 if(version != config->getViewVersion())
4186 __SUP_SS__ <<
"Target table version (" << version
4187 <<
") is not the currently active version ("
4188 << config->getViewVersion() <<
". Try refreshing the tree."
4194 temporaryVersion = config->createTemporaryView(version);
4196 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
4198 cfgView = config->getTemporaryView(temporaryVersion);
4200 col = cfgView->getColLinkGroupID(linkIndex);
4202 __SUP_COUT__ <<
"target col " << col << __E__;
4205 std::vector<std::string> memberUIDs;
4208 csvIndexStart = csvIndex + 1;
4209 csvIndex = newValue.find(
',', csvIndexStart);
4210 memberUIDs.push_back(
4211 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
4212 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
4213 }
while(csvIndex != (
unsigned int)std::string::npos);
4223 std::string targetUID;
4224 bool shouldBeInGroup;
4225 bool defaultIsInGroup =
4229 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
4231 targetUID = cfgView->getDataView()[row][cfgView->getColUID()];
4232 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4234 shouldBeInGroup =
false;
4235 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
4236 if(targetUID == memberUIDs[i])
4239 shouldBeInGroup =
true;
4243 isInGroup = cfgView->isEntryInGroup(row, linkIndex, newLinkId);
4246 if(shouldBeInGroup && !isInGroup)
4248 __SUP_COUT__ <<
"Changed YES: " << row << __E__;
4249 secondaryChanged =
true;
4251 cfgView->addRowToGroup(row, col, newLinkId);
4254 else if(!shouldBeInGroup && isInGroup)
4256 __SUP_COUT__ <<
"Changed NO: " << row << __E__;
4257 secondaryChanged =
true;
4259 cfgView->removeRowFromGroup(row, col, newLinkId);
4261 else if(targetUID ==
4262 cfgView->getDefaultRowValues()[cfgView->getColUID()] &&
4266 defaultIsInGroup =
true;
4271 if(!secondaryChanged)
4274 <<
"No changes to secondary view. Erasing temporary table."
4276 config->eraseView(temporaryVersion);
4284 saveModifiedVersionXML(xmlOut,
4296 catch(std::runtime_error&
4299 __SUP_COUT__ <<
"Caught error while editing secondary table. "
4300 "Erasing temporary version."
4302 config->eraseView(temporaryVersion);
4303 secondaryChanged =
false;
4306 xmlOut.addTextElementToData(
4308 "Error saving secondary tree node! " + std::string(e.what()));
4316 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
4318 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
4320 <<
"', and selected group members are the same as the "
4322 <<
"No need to save changes to tree." << __E__;
4328 else if(0 && !changed)
4333 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
4335 <<
"' are the same as the current values. No need to save "
4336 "change to tree node."
4346 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
4347 config->eraseView(temporaryVersion);
4351 saveModifiedVersionXML(xmlOut,
4360 catch(std::runtime_error& e)
4362 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
4363 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4364 xmlOut.addTextElementToData(
"Error", ss.str());
4368 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
4369 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4370 xmlOut.addTextElementToData(
"Error", ss.str());
4396 void ConfigurationGUISupervisor::handleGetTableGroupXML(HttpXmlDocument& xmlOut,
4397 ConfigurationManagerRW* cfgMgr,
4398 const std::string& groupName,
4399 TableGroupKey groupKey,
4400 bool ignoreWarnings)
try
4402 char tmpIntStr[100];
4403 DOMElement *parentEl, *configEl;
4426 const GroupInfo& groupInfo = cfgMgr->getGroupInfo(groupName);
4427 const std::set<TableGroupKey>& sortedKeys = groupInfo.keys_;
4429 if(groupKey.isInvalid() ||
4430 sortedKeys.find(groupKey) == sortedKeys.end())
4432 if(sortedKeys.size())
4433 groupKey = *sortedKeys.rbegin();
4434 __SUP_COUT__ <<
"Group key requested was invalid or not found, going with latest "
4435 << groupKey << __E__;
4438 xmlOut.addTextElementToData(
"TableGroupName", groupName);
4439 xmlOut.addTextElementToData(
"TableGroupKey", groupKey.toString());
4442 for(
auto& keyInOrder : sortedKeys)
4443 xmlOut.addTextElementToData(
"HistoricalTableGroupKey", keyInOrder.toString());
4445 parentEl = xmlOut.addTextElementToData(
"TableGroupMembers",
"");
4448 std::map<std::string , TableVersion > memberMap;
4449 std::map<std::string , std::string > groupMemberAliases;
4451 __SUP_COUT__ <<
"groupName=" << groupName << __E__;
4452 __SUP_COUT__ <<
"groupKey=" << groupKey << __E__;
4454 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
4455 std::map<std::string, TableInfo>::const_iterator it;
4461 std::string groupAuthor, groupComment, groupCreationTime, groupTypeString;
4462 std::string accumulateTreeErrors;
4464 __SUP_COUTV__(ignoreWarnings);
4465 cfgMgr->loadTableGroup(groupName,
4470 ignoreWarnings ? 0 :
4471 &accumulateTreeErrors,
4477 &groupMemberAliases);
4479 if(accumulateTreeErrors !=
"")
4481 __SUP_COUTV__(accumulateTreeErrors);
4482 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrors);
4485 xmlOut.addTextElementToData(
"TableGroupAuthor", groupAuthor);
4486 xmlOut.addTextElementToData(
"TableGroupComment", groupComment);
4487 xmlOut.addTextElementToData(
"TableGroupCreationTime", groupCreationTime);
4488 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
4490 catch(
const std::runtime_error& e)
4492 __SUP_SS__ <<
"Table group \"" + groupName +
"(" + groupKey.toString() +
")" +
4493 "\" members can not be loaded!\n\n" + e.what()
4495 __SUP_COUT_ERR__ << ss.str();
4496 xmlOut.addTextElementToData(
"Error", ss.str());
4501 __SUP_SS__ <<
"Table group \"" + groupName +
"(" + groupKey.toString() +
")" +
4502 "\" members can not be loaded!"
4504 __SUP_COUT_ERR__ << ss.str();
4505 xmlOut.addTextElementToData(
"Error", ss.str());
4509 __COUTV__(StringMacros::mapToString(groupMemberAliases));
4511 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
4512 cfgMgr->getVersionAliases();
4514 __SUP_COUT__ <<
"# of table version aliases: " << versionAliases.size() << __E__;
4517 for(
auto& memberPair : memberMap)
4519 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
4522 if(groupMemberAliases.find(memberPair.first) != groupMemberAliases.end())
4523 configEl = xmlOut.addTextElementToParent(
4525 ConfigurationManager::ALIAS_VERSION_PREAMBLE +
4526 groupMemberAliases[memberPair.first],
4529 configEl = xmlOut.addTextElementToParent(
4530 "MemberVersion", memberPair.second.toString(), parentEl);
4532 it = allTableInfo.find(memberPair.first);
4533 if(it == allTableInfo.end())
4535 xmlOut.addTextElementToData(
4536 "Error",
"Table \"" + memberPair.first +
"\" can not be retrieved!");
4540 if(versionAliases.find(it->first) != versionAliases.end())
4541 for(
auto& aliasVersion : versionAliases[it->first])
4542 xmlOut.addTextElementToParent(
4543 "TableExistingVersion",
4544 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
4547 for(
auto& version : it->second.versions_)
4550 xmlOut.addTextElementToParent(
4551 "TableExistingVersion", version.toString(), configEl);
4554 for(
auto& memberPair : memberMap)
4561 xmlOut.addTextElementToParent(
4563 allTableInfo.at(memberPair.first).tablePtr_->getView().getComment(),
4600 catch(std::runtime_error& e)
4602 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
4603 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4604 xmlOut.addTextElementToData(
"Error", ss.str());
4608 __SUP_SS__ << (
"Error!\n\n") << __E__;
4609 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4610 xmlOut.addTextElementToData(
"Error", ss.str());
4654 void ConfigurationGUISupervisor::handleGetTableXML(HttpXmlDocument& xmlOut,
4655 ConfigurationManagerRW* cfgMgr,
4656 const std::string& tableName,
4657 TableVersion version,
4658 bool allowIllegalColumns)
try
4660 char tmpIntStr[100];
4661 DOMElement *parentEl, *subparentEl;
4663 std::string accumulatedErrors =
"";
4665 const std::map<std::string, TableInfo>&
4667 cfgMgr->getAllTableInfo(allowIllegalColumns,
4668 allowIllegalColumns ? &accumulatedErrors : 0,
4671 TableBase* table = cfgMgr->getTableByName(tableName);
4675 xmlOut.addTextElementToData(
"ExistingTableNames",
4676 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
4677 for(
auto& configPair : allTableInfo)
4679 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
4680 if(configPair.first == tableName &&
4681 configPair.second.versions_.find(version) == configPair.second.versions_.end())
4683 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
4684 version = TableVersion();
4688 xmlOut.addTextElementToData(
"TableName", tableName);
4689 xmlOut.addTextElementToData(
"TableDescription",
4690 table->getTableDescription());
4697 std::map<std::string , TableVersion >>
4702 versionAliases = cfgMgr->getVersionAliases();
4703 for(
const auto& aliases : versionAliases)
4704 for(
const auto& alias : aliases.second)
4705 __SUP_COUT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
4706 <<
" ==> " << alias.second << __E__;
4708 catch(
const std::runtime_error& e)
4710 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
4711 << e.what() << __E__;
4714 auto tableIterator = versionAliases.find(tableName);
4716 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
4717 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
4720 xmlOut.addTextElementToParent(
"Version", v.toString(), parentEl);
4722 if(tableIterator != versionAliases.end())
4725 for(
const auto& aliasPair : tableIterator->second)
4733 if(v == aliasPair.second)
4735 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
4736 << aliasPair.first << __E__;
4737 xmlOut.addTextElementToParent(
4738 "VersionAlias", aliasPair.first, subparentEl);
4748 TableView* cfgViewPtr;
4749 if(version.isInvalid())
4751 cfgViewPtr = table->getMockupViewP();
4757 cfgViewPtr = cfgMgr->getVersionedTableByName(tableName, version)->getViewP();
4759 catch(std::runtime_error& e)
4761 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
4762 <<
"... defaulting to mock-up! " << __E__;
4763 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
4765 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4766 version = TableVersion();
4767 cfgViewPtr = table->getMockupViewP();
4769 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4773 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
4774 <<
"... defaulting to mock-up! "
4775 <<
"(You may want to try again to see what was partially loaded "
4776 "into cache before failure. "
4777 <<
"If you think, the failure is due to a column name change, "
4778 <<
"you can also try to Copy the failing view to the new column "
4780 <<
"'Copy and Move' functionality.)" << __E__;
4782 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4783 version = TableVersion();
4784 cfgViewPtr = table->getMockupViewP();
4786 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
4789 xmlOut.addTextElementToData(
"TableVersion", version.toString());
4792 DOMElement* choicesParentEl;
4793 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
4795 std::vector<TableViewColumnInfo> colInfo = cfgViewPtr->getColumnsInfo();
4797 for(
int i = 0; i < (int)colInfo.size(); ++i)
4805 xmlOut.addTextElementToParent(
"ColumnHeader", colInfo[i].getName(), parentEl);
4806 xmlOut.addTextElementToParent(
"ColumnType", colInfo[i].getType(), parentEl);
4807 xmlOut.addTextElementToParent(
4808 "ColumnDataType", colInfo[i].getDataType(), parentEl);
4810 choicesParentEl = xmlOut.addTextElementToParent(
"ColumnChoices",
"", parentEl);
4812 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
4813 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
4814 colInfo[i].isChildLink())
4816 for(
auto& choice : colInfo[i].getDataChoices())
4817 xmlOut.addTextElementToParent(
"ColumnChoice", choice, choicesParentEl);
4824 if(version.isInvalid())
4827 catch(std::runtime_error& e)
4830 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
4837 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
4839 for(
int r = 0; r < (int)cfgViewPtr->getNumberOfRows(); ++r)
4843 sprintf(tmpIntStr,
"%d", r);
4844 DOMElement* tmpParentEl =
4845 xmlOut.addTextElementToParent(
"Row", tmpIntStr, parentEl);
4847 for(
int c = 0; c < (int)cfgViewPtr->getNumberOfColumns(); ++c)
4849 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
4851 std::string timeAsString;
4852 cfgViewPtr->getValue(timeAsString, r, c);
4853 xmlOut.addTextElementToParent(
"Entry", timeAsString, tmpParentEl);
4856 xmlOut.addTextElementToParent(
4857 "Entry", cfgViewPtr->getDataView()[r][c], tmpParentEl);
4862 xmlOut.addTextElementToData(
"TableComment", cfgViewPtr->getComment());
4863 xmlOut.addTextElementToData(
"TableAuthor", cfgViewPtr->getAuthor());
4864 xmlOut.addTextElementToData(
"TableCreationTime",
4865 std::to_string(cfgViewPtr->getCreationTime()));
4866 xmlOut.addTextElementToData(
"TableLastAccessTime",
4867 std::to_string(cfgViewPtr->getLastAccessTime()));
4870 std::vector<std::string> defaultRowValues = cfgViewPtr->getDefaultRowValues();
4872 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
4877 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
4880 if(accumulatedErrors !=
"")
4882 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
4883 "maybe you can ignore this, ") +
4884 "but please note the following errors:\n" + accumulatedErrors)
4886 __SUP_COUT_ERR__ << ss.str();
4887 xmlOut.addTextElementToData(
"Error", ss.str());
4889 else if(!version.isTemporaryVersion() &&
4891 (cfgViewPtr->getDataColumnSize() != cfgViewPtr->getNumberOfColumns() ||
4892 cfgViewPtr->getSourceColumnMismatch() !=
4895 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
4896 <<
":v" << version <<
". Please see the details below:\n\n"
4897 <<
"The source column size was found to be "
4898 << cfgViewPtr->getDataColumnSize()
4899 <<
", and the current number of columns for this table is "
4900 << cfgViewPtr->getNumberOfColumns() <<
". This resulted in a count of "
4901 << cfgViewPtr->getSourceColumnMismatch()
4902 <<
" source column mismatches, and a count of "
4903 << cfgViewPtr->getSourceColumnMissing() <<
" table entries missing in "
4904 << cfgViewPtr->getNumberOfRows() <<
" row(s) of data." << __E__;
4906 const std::set<std::string> srcColNames = cfgViewPtr->getSourceColumnNames();
4907 ss <<
"\n\nSource column names in ALPHABETICAL order were as follows:\n";
4909 std::string preIndexStr =
"";
4910 for(
auto& srcColName : srcColNames)
4912 ss <<
"\n\t" << preIndexStr << index <<
". " << srcColName;
4923 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
4924 ss <<
"\n\nCurrent table column names in ALPHABETICAL order are as follows:\n";
4927 for(
auto& destColName : destColNames)
4929 ss <<
"\n\t" << preIndexStr << index <<
". " << destColName;
4940 __SUP_COUT__ <<
"\n" << ss.str();
4941 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
4944 catch(std::runtime_error& e)
4946 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
4947 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + std::string(e.what()));
4951 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
4952 xmlOut.addTextElementToData(
"Error",
"Error getting view! ");
4960 TableVersion ConfigurationGUISupervisor::saveModifiedVersionXML(
4961 HttpXmlDocument& xmlOut,
4962 ConfigurationManagerRW* cfgMgr,
4963 const std::string& tableName,
4964 TableVersion originalVersion,
4967 TableVersion temporaryModifiedVersion,
4968 bool ignoreDuplicates,
4969 bool lookForEquivalent)
4971 bool needToEraseTemporarySource =
4972 (originalVersion.isTemporaryVersion() && !makeTemporary);
4975 if(!ignoreDuplicates)
4977 __SUP_COUT__ <<
"Checking for duplicate tables..." << __E__;
4979 TableVersion duplicateVersion;
4986 const std::map<std::string, TableInfo>& allTableInfo =
4987 cfgMgr->getAllTableInfo();
4989 auto versionReverseIterator =
4990 allTableInfo.at(tableName).versions_.rbegin();
4991 __SUP_COUT__ <<
"Filling up cached from " << config->getNumberOfStoredViews()
4992 <<
" to max count of " << config->MAX_VIEWS_IN_CACHE << __E__;
4993 for(; config->getNumberOfStoredViews() < config->MAX_VIEWS_IN_CACHE &&
4994 versionReverseIterator != allTableInfo.at(tableName).versions_.rend();
4995 ++versionReverseIterator)
4997 __SUP_COUT__ <<
"Versions in reverse order " << *versionReverseIterator
5001 cfgMgr->getVersionedTableByName(
5002 tableName, *versionReverseIterator);
5004 catch(
const std::runtime_error& e)
5007 <<
"Error loadiing historical version, but ignoring: " << e.what()
5013 __SUP_COUT__ <<
"Checking duplicate..." << __E__;
5015 duplicateVersion = config->checkForDuplicate(
5016 temporaryModifiedVersion,
5017 (!originalVersion.isTemporaryVersion() && !makeTemporary)
5023 if(lookForEquivalent && !duplicateVersion.isInvalid())
5026 __SUP_COUT__ <<
"Equivalent table found in version v" << duplicateVersion
5030 if(duplicateVersion.isTemporaryVersion() && !makeTemporary)
5032 __SUP_COUT__ <<
"Need persistent. Duplicate version was temporary. "
5033 "Abandoning duplicate."
5035 duplicateVersion = TableVersion();
5042 cfgMgr->eraseTemporaryVersion(tableName, temporaryModifiedVersion);
5045 if(needToEraseTemporarySource)
5046 cfgMgr->eraseTemporaryVersion(tableName, originalVersion);
5048 xmlOut.addTextElementToData(
"savedName", tableName);
5049 xmlOut.addTextElementToData(
"savedVersion", duplicateVersion.toString());
5050 xmlOut.addTextElementToData(
"foundEquivalentVersion",
"1");
5052 __SUP_COUT__ <<
"\t\t equivalent AssignedVersion: " << duplicateVersion
5055 return duplicateVersion;
5059 if(!duplicateVersion.isInvalid())
5061 __SUP_SS__ <<
"This version of table '" << tableName
5062 <<
"' is identical to another version currently cached v"
5063 << duplicateVersion <<
". No reason to save a duplicate." << __E__;
5064 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5067 config->eraseView(temporaryModifiedVersion);
5071 __SUP_COUT__ <<
"Check for duplicate tables complete." << __E__;
5075 __SUP_COUT__ <<
"\t\t**************************** Save as temporary table version"
5078 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
5081 TableVersion newAssignedVersion =
5082 cfgMgr->saveNewTable(tableName, temporaryModifiedVersion, makeTemporary);
5084 if(needToEraseTemporarySource)
5085 cfgMgr->eraseTemporaryVersion(tableName, originalVersion);
5087 xmlOut.addTextElementToData(
"savedName", tableName);
5088 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
5090 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
5091 return newAssignedVersion;
5102 void ConfigurationGUISupervisor::handleCreateTableXML(HttpXmlDocument& xmlOut,
5103 ConfigurationManagerRW* cfgMgr,
5104 const std::string& tableName,
5105 TableVersion version,
5107 const std::string& data,
5108 const int& dataOffset,
5109 const std::string& author,
5110 const std::string& comment,
5111 bool sourceTableAsIs,
5112 bool lookForEquivalent)
try
5121 if(!version.isInvalid())
5126 cfgMgr->getVersionedTableByName(tableName, version);
5131 version = TableVersion();
5135 TableBase* config = cfgMgr->getTableByName(tableName);
5139 if(!version.isInvalid())
5143 if(config->getViewP()->getDataColumnSize() !=
5144 config->getMockupViewP()->getNumberOfColumns() ||
5145 config->getViewP()->getSourceColumnMismatch() != 0)
5147 __SUP_COUT__ <<
"config->getViewP()->getNumberOfColumns() "
5148 << config->getViewP()->getNumberOfColumns() << __E__;
5149 __SUP_COUT__ <<
"config->getMockupViewP()->getNumberOfColumns() "
5150 << config->getMockupViewP()->getNumberOfColumns() << __E__;
5151 __SUP_COUT__ <<
"config->getViewP()->getSourceColumnMismatch() "
5152 << config->getViewP()->getSourceColumnMismatch() << __E__;
5154 <<
"Source view v" << version
5155 <<
" has a mismatch in the number of columns, so using mockup as source."
5157 version = TableVersion();
5162 TableVersion temporaryVersion = config->createTemporaryView(version);
5164 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << __E__;
5166 TableView* cfgView = config->getTemporaryView(temporaryVersion);
5172 retVal = sourceTableAsIs ? 0 : cfgView->fillFromCSV(data, dataOffset, author);
5176 __SUP_COUT__ <<
"Data was the same, but columns have changed!" << __E__;
5177 __SUP_COUTV__(sourceTableAsIs);
5178 lookForEquivalent =
false;
5181 cfgView->setURIEncodedComment(comment);
5182 __SUP_COUT__ <<
"Table comment was set to:\n\t" << cfgView->getComment() << __E__;
5186 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5187 config->eraseView(temporaryVersion);
5197 if(retVal < 0 && (!version.isTemporaryVersion() || makeTemporary) &&
5198 ConfigurationInterface::isVersionTrackingEnabled())
5200 if(!version.isInvalid() &&
5202 !version.isScratchVersion())
5206 <<
"No rows were modified! No reason to fill a view with same content."
5208 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5210 config->eraseView(temporaryVersion);
5213 else if(version.isInvalid())
5214 __SUP_COUT__ <<
"This was interpreted as an attempt to create a blank table."
5216 else if(version.isScratchVersion())
5217 __SUP_COUT__ <<
"This was interpreted as an attempt to make a persistent "
5218 "version of the scratch table."
5223 __THROW__(ss.str() +
"impossible!");
5226 else if(retVal < 0 && (version.isTemporaryVersion() && !makeTemporary))
5228 __SUP_COUT__ <<
"Allowing the static data because this is converting from "
5229 "temporary to persistent version."
5232 else if(retVal < 0 && !ConfigurationInterface::isVersionTrackingEnabled())
5234 __SUP_COUT__ <<
"Allowing the static data because version tracking is OFF."
5239 __SUP_SS__ <<
"This should not be possible! Fatal error." << __E__;
5241 config->eraseView(temporaryVersion);
5246 saveModifiedVersionXML(xmlOut,
5254 lookForEquivalent || sourceTableAsIs );
5256 catch(std::runtime_error& e)
5258 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
5259 xmlOut.addTextElementToData(
"Error",
5260 "Error saving new view!\n " + std::string(e.what()));
5264 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
5265 xmlOut.addTextElementToData(
"Error",
"Error saving new view! ");
5279 ConfigurationManagerRW* ConfigurationGUISupervisor::refreshUserSession(
5280 std::string username, uint64_t activeSessionIndex,
bool refresh)
5283 activeSessionIndex =
5286 std::stringstream ssMapKey;
5287 ssMapKey << username <<
":" << activeSessionIndex;
5288 std::string mapKey = ssMapKey.str();
5289 __SUP_COUT__ <<
"Config Session: " << mapKey
5290 <<
" ... out of size: " << userConfigurationManagers_.size() << __E__;
5292 time_t now = time(0);
5295 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
5297 __SUP_COUT_INFO__ <<
"Creating new Configuration Manager." << __E__;
5298 userConfigurationManagers_[mapKey] =
new ConfigurationManagerRW(username);
5303 userConfigurationManagers_[mapKey]->getAllTableInfo(
5306 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
5308 __SUP_SS__ <<
"Fatal error managing userLastUseTime_!" << __E__;
5309 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5312 else if(refresh || (now - userLastUseTime_[mapKey]) >
5313 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
5317 __SUP_COUT_INFO__ <<
"Refreshing all table info." << __E__;
5318 userConfigurationManagers_[mapKey]->getAllTableInfo(
true);
5327 userLastUseTime_[mapKey] = now;
5330 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
5331 it != userLastUseTime_.end();
5333 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
5335 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
5337 delete userConfigurationManagers_[it->first];
5338 if(!(userConfigurationManagers_.erase(it->first)))
5340 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
5342 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5345 userLastUseTime_.erase(it);
5347 it = userLastUseTime_.begin();
5352 return userConfigurationManagers_[mapKey];
5374 void ConfigurationGUISupervisor::handleCreateTableGroupXML(
5375 HttpXmlDocument& xmlOut,
5376 ConfigurationManagerRW* cfgMgr,
5377 const std::string& groupName,
5378 const std::string& tableList,
5379 bool allowDuplicates,
5380 bool ignoreWarnings,
5381 const std::string& groupComment,
5382 bool lookForEquivalent)
try
5384 __SUP_COUT__ <<
"handleCreateTableGroupXML \n";
5386 xmlOut.addTextElementToData(
"AttemptedNewGroupName", groupName);
5390 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
true);
5391 cfgMgr->loadConfigurationBackbone();
5393 std::map<std::string ,
5394 std::map<std::string , TableVersion >>
5395 versionAliases = cfgMgr->getVersionAliases();
5401 std::map<std::string , TableVersion > groupMembers;
5402 std::map<std::string , std::string > groupAliases;
5404 std::string name, versionStr, alias;
5405 TableVersion version;
5406 auto c = tableList.find(
',', 0);
5409 while(c < tableList.length())
5412 name = tableList.substr(i, c - i);
5414 c = tableList.find(
',', i);
5415 if(c == std::string::npos)
5417 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
5418 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5419 xmlOut.addTextElementToData(
"Error", ss.str());
5423 versionStr = tableList.substr(i, c - i);
5425 c = tableList.find(
',', i);
5431 if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
5434 versionStr.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
5436 __SUP_COUT__ <<
"Found alias " << name <<
" " << versionStr << __E__;
5439 if(versionAliases.find(name) != versionAliases.end() &&
5440 versionAliases[name].find(alias) != versionAliases[name].end())
5442 version = versionAliases[name][alias];
5443 __SUP_COUT__ <<
"version alias '" << alias
5444 <<
"'translated to: " << version << __E__;
5446 groupAliases[name] = alias;
5450 __SUP_SS__ <<
"version alias '"
5451 << versionStr.substr(
5452 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
5453 <<
"' was not found in active version aliases!" << __E__;
5454 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5455 xmlOut.addTextElementToData(
"Error", ss.str());
5460 version = TableVersion(versionStr);
5462 if(version.isTemporaryVersion())
5464 __SUP_SS__ <<
"Groups can not be created using temporary member tables. "
5465 <<
"Table member '" << name <<
"' with temporary version '"
5466 << version <<
"' is illegal." << __E__;
5467 xmlOut.addTextElementToData(
"Error", ss.str());
5472 if(allTableInfo.find(name) == allTableInfo.end())
5474 __SUP_SS__ <<
"Groups can not be created using mock-up member tables of "
5475 "undefined tables. "
5476 <<
"Table member '" << name <<
"' is not defined." << __E__;
5477 xmlOut.addTextElementToData(
"Error", ss.str());
5481 if(version.isMockupVersion())
5484 TableBase* config = cfgMgr->getTableByName(name);
5486 TableVersion temporaryVersion = config->createTemporaryView();
5487 __SUP_COUT__ <<
"\t\ttemporaryVersion: " << temporaryVersion << __E__;
5490 __SUP_COUT__ <<
"Creating version from mock-up for name: " << name
5491 <<
" inputVersionStr: " << versionStr << __E__;
5494 config->getTemporaryView(temporaryVersion)
5495 ->setComment(
"Auto-generated from mock-up.");
5499 saveModifiedVersionXML(xmlOut,
5509 __SUP_COUT__ <<
"Using mockup version: " << version << __E__;
5513 groupMembers[name] = version;
5516 __COUTV__(StringMacros::mapToString(groupAliases));
5518 if(!allowDuplicates)
5520 __SUP_COUT__ <<
"Checking for duplicate groups..." << __E__;
5521 TableGroupKey foundKey =
5522 cfgMgr->findTableGroup(groupName, groupMembers, groupAliases);
5524 if(!foundKey.isInvalid())
5527 xmlOut.addTextElementToData(
"TableGroupName", groupName);
5528 xmlOut.addTextElementToData(
"TableGroupKey", foundKey.toString());
5530 if(lookForEquivalent)
5532 __SUP_COUT__ <<
"Found equivalent group key (" << foundKey <<
") for "
5533 << groupName <<
"." << __E__;
5535 xmlOut.addTextElementToData(
"foundEquivalentKey",
"1");
5538 handleGetTableGroupXML(
5539 xmlOut, cfgMgr, groupName, foundKey, ignoreWarnings);
5544 __SUP_COUT__ <<
"Treating duplicate group as error." << __E__;
5545 __SUP_SS__ << (
"Failed to create table group: " + groupName +
5546 ". It is a duplicate of an existing group key (" +
5547 foundKey.toString() +
")");
5548 __SUP_COUT_ERR__ << ss.str() << __E__;
5549 xmlOut.addTextElementToData(
"Error", ss.str());
5554 __SUP_COUT__ <<
"Check for duplicate groups complete." << __E__;
5560 cfgMgr->loadMemberMap(groupMembers);
5562 std::string accumulateErrors =
"";
5563 for(
auto& groupMemberPair : groupMembers)
5565 TableView* cfgViewPtr =
5566 cfgMgr->getTableByName(groupMemberPair.first)->getViewP();
5567 if(cfgViewPtr->getDataColumnSize() != cfgViewPtr->getNumberOfColumns() ||
5568 cfgViewPtr->getSourceColumnMismatch() !=
5571 __SUP_SS__ <<
"\n\nThere were errors found in loading a member table "
5572 << groupMemberPair.first <<
":v" << cfgViewPtr->getVersion()
5573 <<
". Please see the details below:\n\n"
5574 <<
"The source column size was found to be "
5575 << cfgViewPtr->getDataColumnSize()
5576 <<
", and the current number of columns for this table is "
5577 << cfgViewPtr->getNumberOfColumns()
5578 <<
". This resulted in a count of "
5579 << cfgViewPtr->getSourceColumnMismatch()
5580 <<
" source column mismatches, and a count of "
5581 << cfgViewPtr->getSourceColumnMissing()
5582 <<
" table entries missing in "
5583 << cfgViewPtr->getNumberOfRows() <<
" row(s) of data."
5586 const std::set<std::string> srcColNames =
5587 cfgViewPtr->getSourceColumnNames();
5588 ss <<
"\n\nSource column names were as follows:\n";
5590 for(
auto& srcColName : srcColNames)
5591 ss <<
"\n\t" << index++ <<
". " << srcColName;
5594 std::set<std::string> destColNames = cfgViewPtr->getColumnStorageNames();
5595 ss <<
"\n\nCurrent table column names are as follows:\n";
5597 for(
auto& destColName : destColNames)
5598 ss <<
"\n\t" << index++ <<
". " << destColName;
5601 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5602 xmlOut.addTextElementToData(
"Error", ss.str());
5607 catch(std::runtime_error& e)
5609 __SUP_SS__ <<
"Failed to create config group: " << groupName
5610 <<
".\nThere were problems loading the chosen members:\n\n"
5611 << e.what() << __E__;
5612 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5613 xmlOut.addTextElementToData(
"Error", ss.str());
5618 __SUP_SS__ <<
"Failed to create config group: " << groupName << __E__;
5619 __SUP_COUT_ERR__ <<
"\n" << ss.str();
5620 xmlOut.addTextElementToData(
"Error", ss.str());
5625 std::string accumulateTreeErrs;
5626 cfgMgr->getChildren(&groupMembers, &accumulateTreeErrs);
5627 if(accumulateTreeErrs !=
"")
5629 __SUP_COUT_WARN__ <<
"\n" << accumulateTreeErrs << __E__;
5632 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
5637 TableGroupKey newKey;
5640 __COUT__ <<
"Saving new group..." << __E__;
5641 newKey = cfgMgr->saveNewTableGroup(
5642 groupName, groupMembers, groupComment, &groupAliases);
5644 catch(std::runtime_error& e)
5646 __SUP_COUT_ERR__ <<
"Failed to create config group: " << groupName << __E__;
5647 __SUP_COUT_ERR__ <<
"\n\n" << e.what() << __E__;
5648 xmlOut.addTextElementToData(
5649 "Error",
"Failed to create table group: " + groupName +
".\n\n" + e.what());
5654 __SUP_COUT_ERR__ <<
"Failed to create table group: " << groupName << __E__;
5655 xmlOut.addTextElementToData(
"Error",
5656 "Failed to create table group: " + groupName);
5661 __COUT__ <<
"Loading new table group..." << __E__;
5662 handleGetTableGroupXML(xmlOut, cfgMgr, groupName, newKey, ignoreWarnings);
5665 catch(std::runtime_error& e)
5667 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
5668 xmlOut.addTextElementToData(
"Error",
5669 "Error saving table group! " + std::string(e.what()));
5673 __SUP_COUT__ <<
"Unknown Error detected!\n\n " << __E__;
5674 xmlOut.addTextElementToData(
"Error",
"Error saving table group! ");
5682 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(HttpXmlDocument& xmlOut,
5683 ConfigurationManagerRW* cfgMgr,
5684 std::string& tableName)
5686 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
5687 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
5688 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
5689 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5693 __SUP_COUT_ERR__ << (
"Error renaming file to " +
5694 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5697 xmlOut.addTextElementToData(
5699 (
"Error renaming Table Info File to " +
5700 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
5705 cfgMgr->getAllTableInfo(
true);
5715 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
5716 HttpXmlDocument& xmlOut,
5717 ConfigurationManagerRW* cfgMgr,
5718 std::string& tableName,
5719 const std::string& data,
5720 const std::string& tableDescription,
5721 const std::string& columnChoicesCSV,
5722 bool allowOverwrite)
5726 std::string capsName;
5729 capsName = TableBase::convertToCaps(tableName,
true);
5731 catch(std::runtime_error& e)
5733 xmlOut.addTextElementToData(
"Error", e.what());
5739 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
5743 xmlOut.addTextElementToData(
"TableName", tableName);
5744 xmlOut.addTextElementToData(
"OverwriteError",
"1");
5745 xmlOut.addTextElementToData(
5747 "File already exists! ('" +
5748 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
5753 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
5754 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
5755 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
5756 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
5759 std::stringstream outss;
5761 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
5762 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
5763 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
5764 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
5765 outss <<
"\t\t\t<VIEW Name=\"" << capsName
5766 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
5772 int j = data.find(
',', i);
5773 int k = data.find(
';', i);
5775 std::istringstream columnChoicesISS(columnChoicesCSV);
5776 std::string columnChoicesString;
5777 std::string columnType;
5779 while(k != (
int)(std::string::npos))
5782 columnType = data.substr(i, j - i);
5783 outss <<
"\t\t\t\t<COLUMN Type=\"";
5784 outss << columnType;
5787 j = data.find(
',', i);
5790 outss <<
"\" \t Name=\"";
5791 capsName = data.substr(i, j - i);
5793 outss <<
"\" \t StorageName=\"";
5797 outss << TableBase::convertToCaps(capsName);
5799 catch(std::runtime_error& e)
5801 xmlOut.addTextElementToData(
"Error",
5802 std::string(
"For column name '") +
5803 data.substr(i, j - i) +
"' - " + e.what());
5808 j = data.find(
',', i);
5811 outss <<
"\" \t DataType=\"";
5812 outss << data.substr(i, k - i);
5815 getline(columnChoicesISS, columnChoicesString,
';');
5817 outss <<
"\" \t DataChoices=\"";
5818 outss << columnChoicesString;
5824 j = data.find(
',', i);
5825 k = data.find(
';', i);
5828 outss <<
"\t\t\t</VIEW>\n";
5829 outss <<
"\t\t</TABLE>\n";
5830 outss <<
"\t</ROOT>\n";
5832 __SUP_COUT__ << outss.str() << __E__;
5834 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
5837 xmlOut.addTextElementToData(
"Error",
5838 "Failed to open destination Table Info file:" +
5839 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
5843 fprintf(fp,
"%s", outss.str().c_str());
5848 std::string accumulatedErrors =
"";
5849 cfgMgr->getAllTableInfo(
true, &accumulatedErrors, tableName);
5852 if(accumulatedErrors !=
"")
5854 __SUP_SS__ << (
"The new version of the '" + tableName +
5855 "' table column info was saved, however errors were detected "
5856 "reading back the table '" +
5857 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
5860 __SUP_COUT_ERR__ << ss.str() << __E__;
5861 xmlOut.addTextElementToData(
"Error", ss.str());
5873 rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
5874 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
5876 << (
"File successfully renamed: " +
5877 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5882 << (
"Error renaming file to " +
5883 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
5887 cfgMgr->getAllTableInfo(
true);
5893 handleGetTableXML(xmlOut, cfgMgr, tableName, TableVersion());
5897 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
5900 __SUP_COUT_INFO__ <<
"Looking for errors in all table column info..." << __E__;
5901 for(
const auto& cfgInfo : allTableInfo)
5905 cfgMgr->getTableByName(cfgInfo.first)->getMockupViewP()->init();
5907 catch(std::runtime_error& e)
5909 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
5910 <<
"Error identified in column info of table '"
5911 << cfgInfo.first <<
"':\n\n"
5912 << e.what() <<
"\n\n"
5926 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
5927 HttpXmlDocument& xmlOut,
5928 ConfigurationManagerRW* cfgMgr,
5929 const std::string& groupAlias,
5930 const std::string& groupName,
5931 TableGroupKey groupKey,
5932 const std::string& author)
try
5934 cfgMgr->loadConfigurationBackbone();
5935 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
5937 const std::string groupAliasesTableName =
5938 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
5939 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
5941 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
5943 xmlOut.addTextElementToData(
"Error", ss.str());
5948 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
5949 for(
auto& memberName : backboneMembers)
5951 __SUP_COUT__ <<
"activeVersions[\"" << memberName
5952 <<
"\"]=" << activeVersions[memberName] << __E__;
5954 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
5955 xmlOut.addTextElementToData(
"oldBackboneVersion",
5956 activeVersions[memberName].toString());
5963 TableBase* config = cfgMgr->getTableByName(groupAliasesTableName);
5964 TableVersion originalVersion = activeVersions[groupAliasesTableName];
5965 TableVersion temporaryVersion = config->createTemporaryView(originalVersion);
5967 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
5968 bool isDifferent =
false;
5972 TableView* configView = config->getTemporaryView(temporaryVersion);
5974 unsigned int col = configView->findCol(
"GroupKeyAlias");
5978 unsigned int row = -1;
5982 row = configView->findRow(col, groupAlias);
5987 if(row == (
unsigned int)-1)
5990 row = configView->addRow();
5993 col = configView->findCol(
"CommentDescription");
5994 configView->setValue(
5995 "This Group Alias was automatically setup by the server.", row, col);
5996 col = configView->findCol(
"GroupKeyAlias");
5997 configView->setValue(groupAlias, row, col);
6000 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6002 col = configView->findCol(
"GroupName");
6004 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6005 << configView->getDataView()[row][col] << __E__;
6006 if(groupName != configView->getDataView()[row][col])
6008 configView->setValue(groupName, row, col);
6012 col = configView->findCol(
"GroupKey");
6013 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6014 << configView->getDataView()[row][col] << __E__;
6015 if(groupKey.toString() != configView->getDataView()[row][col])
6017 configView->setValue(groupKey.toString(), row, col);
6023 configView->setValue(author, row, configView->findCol(
"Author"));
6024 configView->setValue(
6025 time(0), row, configView->findCol(
"RecordInsertionTime"));
6030 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6033 config->eraseView(temporaryVersion);
6037 TableVersion newAssignedVersion;
6040 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6048 newAssignedVersion = saveModifiedVersionXML(xmlOut,
6050 config->getTableName(),
6061 <<
"\t\t**************************** Using the existing table version"
6065 config->eraseView(temporaryVersion);
6066 newAssignedVersion = activeVersions[groupAliasesTableName];
6068 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6069 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6072 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6074 catch(std::runtime_error& e)
6076 __SUP_COUT_ERR__ <<
"Error detected!\n\n " << e.what() << __E__;
6077 xmlOut.addTextElementToData(
6078 "Error",
"Error saving new Group Alias view!\n " + std::string(e.what()));
6082 __SUP_COUT_ERR__ <<
"Error detected!\n\n " << __E__;
6083 xmlOut.addTextElementToData(
"Error",
"Error saving new Group Alias view! ");
6094 void ConfigurationGUISupervisor::handleSetVersionAliasInBackboneXML(
6095 HttpXmlDocument& xmlOut,
6096 ConfigurationManagerRW* cfgMgr,
6097 const std::string& versionAlias,
6098 const std::string& tableName,
6099 TableVersion version,
6100 const std::string& author)
try
6102 cfgMgr->loadConfigurationBackbone();
6103 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6105 const std::string versionAliasesTableName =
6106 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6107 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6109 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6111 xmlOut.addTextElementToData(
"Error", ss.str());
6116 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6117 for(
auto& memberName : backboneMembers)
6119 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6120 <<
"\"]=" << activeVersions[memberName] << __E__;
6122 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6123 xmlOut.addTextElementToData(
"oldBackboneVersion",
6124 activeVersions[memberName].toString());
6131 TableBase* config = cfgMgr->getTableByName(versionAliasesTableName);
6132 TableVersion originalVersion = activeVersions[versionAliasesTableName];
6133 TableVersion temporaryVersion = config->createTemporaryView(originalVersion);
6135 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6137 bool isDifferent =
false;
6141 TableView* configView = config->getTemporaryView(temporaryVersion);
6144 unsigned int col2 = configView->findCol(
"VersionAlias");
6145 unsigned int col3 = configView->findCol(
"TableName");
6149 unsigned int row = -1;
6154 unsigned int tmpRow = -1;
6157 tmpRow = configView->findRow(col3, tableName, tmpRow + 1);
6158 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
6165 if(row == (
unsigned int)-1)
6168 row = configView->addRow();
6171 col = configView->findCol(
"CommentDescription");
6172 configView->setValue(
6173 std::string(
"Entry was added by server in ") +
6174 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone().",
6178 col = configView->findCol(
"VersionAliasUID");
6179 configView->setValue(
6180 tableName.substr(0, tableName.rfind(
"Table")) + versionAlias, row, col);
6182 configView->setValue(versionAlias, row, col2);
6183 configView->setValue(tableName, row, col3);
6186 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6188 col = configView->findCol(
"Version");
6189 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
6190 << configView->getDataView()[row][col] << __E__;
6191 if(version.toString() != configView->getDataView()[row][col])
6193 configView->setValue(version.toString(), row, col);
6199 configView->setValue(author, row, configView->findCol(
"Author"));
6200 configView->setValue(
6201 time(0), row, configView->findCol(
"RecordInsertionTime"));
6206 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
6209 config->eraseView(temporaryVersion);
6213 TableVersion newAssignedVersion;
6216 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6222 newAssignedVersion = saveModifiedVersionXML(xmlOut,
6224 config->getTableName(),
6234 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
6238 config->eraseView(temporaryVersion);
6239 newAssignedVersion = activeVersions[versionAliasesTableName];
6241 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
6242 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6245 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6247 catch(std::runtime_error& e)
6249 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
6250 xmlOut.addTextElementToData(
6251 "Error",
"Error saving new Version Alias view!\n " + std::string(e.what()));
6255 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
6256 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
6265 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
6266 HttpXmlDocument& xmlOut,
6267 ConfigurationManagerRW* cfgMgr,
6268 const std::string& versionAlias,
6269 const std::string& groupName,
6270 TableGroupKey groupKey,
6271 const std::string& author)
try
6273 cfgMgr->loadConfigurationBackbone();
6274 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6276 const std::string versionAliasesTableName =
6277 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6278 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6280 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6282 xmlOut.addTextElementToData(
"Error", ss.str());
6287 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6288 for(
auto& memberName : backboneMembers)
6290 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6291 <<
"\"]=" << activeVersions[memberName] << __E__;
6293 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6294 xmlOut.addTextElementToData(
"oldBackboneVersion",
6295 activeVersions[memberName].toString());
6302 TableBase* config = cfgMgr->getTableByName(versionAliasesTableName);
6303 TableVersion temporaryVersion =
6304 config->createTemporaryView(activeVersions[versionAliasesTableName]);
6306 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6308 TableView* configView = config->getTemporaryView(temporaryVersion);
6311 bool isDifferent =
false;
6314 std::map<std::string , TableVersion > memberMap;
6317 cfgMgr->loadTableGroup(groupName,
6330 xmlOut.addTextElementToData(
6332 "Table group \"" + TableGroupKey::getFullGroupString(groupName, groupKey) +
6333 "\" can not be retrieved!");
6338 unsigned int col2 = configView->findCol(
"VersionAlias");
6339 unsigned int col3 = configView->findCol(
"TableName");
6341 for(
auto& memberPair : memberMap)
6343 bool thisMemberIsDifferent =
false;
6344 unsigned int row = -1;
6346 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
6347 << memberPair.second <<
" to " << versionAlias << __E__;
6353 unsigned int tmpRow = -1;
6356 tmpRow = configView->findRow(col3, memberPair.first, tmpRow + 1);
6359 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
6366 if(row == (
unsigned int)-1)
6368 thisMemberIsDifferent =
true;
6369 row = configView->addRow();
6372 col = configView->findCol(
"CommentDescription");
6373 configView->setValue(
6374 std::string(
"Entry was added by server in ") +
6375 "ConfigurationGUISupervisor::setVersionAliasInActiveBackbone().",
6379 col = configView->getColUID();
6380 configView->setValue(
6381 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
6386 configView->setValue(versionAlias, row, col2);
6387 configView->setValue(memberPair.first, row, col3);
6392 col = configView->findCol(
"Version");
6396 if(memberPair.second.toString() != configView->getDataView()[row][col])
6398 configView->setValue(memberPair.second.toString(), row, col);
6399 thisMemberIsDifferent =
true;
6402 if(thisMemberIsDifferent)
6404 configView->setValue(author, row, configView->findCol(
"Author"));
6405 configView->setValue(
6406 time(0), row, configView->findCol(
"RecordInsertionTime"));
6409 if(thisMemberIsDifferent)
6415 TableVersion newAssignedVersion;
6418 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
6419 <<
" as new table version" << __E__;
6421 newAssignedVersion =
6422 cfgMgr->saveNewTable(versionAliasesTableName, temporaryVersion);
6426 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
6430 config->eraseView(temporaryVersion);
6431 newAssignedVersion = activeVersions[versionAliasesTableName];
6434 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
6435 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6436 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
6438 catch(std::runtime_error& e)
6440 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
6441 xmlOut.addTextElementToData(
6442 "Error",
"Error saving new Version Alias view!\n " + std::string(e.what()));
6446 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
6447 xmlOut.addTextElementToData(
"Error",
"Error saving new Version Alias view! ");
6461 void ConfigurationGUISupervisor::handleGroupAliasesXML(HttpXmlDocument& xmlOut,
6462 ConfigurationManagerRW* cfgMgr)
6464 cfgMgr->loadConfigurationBackbone();
6465 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6467 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6468 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6470 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
6471 << groupAliasesTableName
6472 <<
" is a required member of the Backbone table group."
6473 <<
"\n\nLikely you need to activate a valid Backbone table group."
6475 xmlOut.addTextElementToData(
"Error", ss.str());
6478 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
6479 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
6480 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
6481 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
6482 activeVersions[groupAliasesTableName].toString());
6484 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
6485 cfgMgr->getNode(groupAliasesTableName).getChildren();
6487 std::string groupName, groupKey, groupComment, groupType;
6488 for(
auto& aliasNodePair : aliasNodePairs)
6490 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
6491 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
6493 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
6494 xmlOut.addTextElementToData(
"GroupName", groupName);
6495 xmlOut.addTextElementToData(
"GroupKey", groupKey);
6496 xmlOut.addTextElementToData(
6498 aliasNodePair.second.getNode(
"CommentDescription").getValueAsString());
6502 groupType =
"Invalid";
6505 cfgMgr->loadTableGroup(groupName,
6506 TableGroupKey(groupKey),
6519 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"(" << groupKey
6520 <<
")' to extract group comment and type." << __E__;
6522 xmlOut.addTextElementToData(
"GroupComment", groupComment);
6523 xmlOut.addTextElementToData(
"GroupType", groupType);
6538 void ConfigurationGUISupervisor::handleVersionAliasesXML(HttpXmlDocument& xmlOut,
6539 ConfigurationManagerRW* cfgMgr)
6541 cfgMgr->loadConfigurationBackbone();
6542 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6544 std::string versionAliasesTableName =
6545 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6546 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6548 __SUP_SS__ <<
"Active version of VersionAliases missing!"
6549 <<
"Make sure you have a valid active Backbone Group." << __E__;
6550 xmlOut.addTextElementToData(
"Error", ss.str());
6553 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
6554 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
6555 xmlOut.addTextElementToData(
"VersionAliasesVersion",
6556 activeVersions[versionAliasesTableName].toString());
6558 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
6559 cfgMgr->getNode(versionAliasesTableName).getChildren();
6561 for(
auto& aliasNodePair : aliasNodePairs)
6565 xmlOut.addTextElementToData(
6567 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
6568 xmlOut.addTextElementToData(
6569 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
6570 xmlOut.addTextElementToData(
6571 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
6572 xmlOut.addTextElementToData(
6574 aliasNodePair.second.getNode(
"CommentDescription").getValueAsString());
6584 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
6585 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr,
const std::string& tableList)
6587 std::map<std::string , TableVersion > memberMap;
6588 std::string name, versionStr;
6589 auto c = tableList.find(
',', 0);
6592 while(c < tableList.length())
6595 name = tableList.substr(i, c - i);
6597 c = tableList.find(
',', i);
6598 if(c == std::string::npos)
6600 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
6601 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6602 xmlOut.addTextElementToData(
"Error", ss.str());
6606 versionStr = tableList.substr(i, c - i);
6608 c = tableList.find(
',', i);
6610 memberMap[name] = TableVersion(versionStr);
6613 std::string groupTypeString =
"";
6618 groupTypeString = cfgMgr->getTypeNameOfGroup(memberMap);
6619 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6621 catch(std::runtime_error& e)
6623 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
6624 __SUP_COUT__ <<
"\n" << ss.str();
6625 groupTypeString =
"Invalid";
6626 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6630 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
6631 __SUP_COUT__ <<
"\n" << ss.str();
6632 groupTypeString =
"Invalid";
6633 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6653 void ConfigurationGUISupervisor::handleTableGroupsXML(HttpXmlDocument& xmlOut,
6654 ConfigurationManagerRW* cfgMgr,
6657 DOMElement* parentEl;
6661 if(!cfgMgr->getAllGroupInfo()
6664 __SUP_COUT__ <<
"Cache is empty? Attempting to regenerate." << __E__;
6665 cfgMgr->getAllTableInfo(
true );
6668 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
6688 TableGroupKey groupKey;
6689 std::string groupName;
6690 std::string groupString, groupTypeString, groupComment, groupCreationTime,
6692 for(
auto& groupInfo : allGroupInfo)
6694 groupName = groupInfo.first;
6695 if(groupInfo.second.keys_.size() == 0)
6697 __SUP_COUT__ <<
"Group name '" << groupName
6698 <<
"' found, but no keys so ignoring." << __E__;
6702 groupKey = *(groupInfo.second.keys_.rbegin());
6704 xmlOut.addTextElementToData(
"TableGroupName", groupName);
6705 xmlOut.addTextElementToData(
"TableGroupKey", groupKey.toString());
6708 xmlOut.addTextElementToData(
"TableGroupType",
6709 groupInfo.second.latestKeyGroupTypeString_);
6710 xmlOut.addTextElementToData(
"TableGroupComment",
6711 groupInfo.second.latestKeyGroupComment_);
6712 xmlOut.addTextElementToData(
"TableGroupAuthor",
6713 groupInfo.second.latestKeyGroupAuthor_);
6714 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6715 groupInfo.second.latestKeyGroupCreationTime_);
6728 parentEl = xmlOut.addTextElementToData(
"TableGroupMembers",
"");
6768 for(
auto& memberPair : groupInfo.second.latestKeyMemberMap_)
6772 xmlOut.addTextElementToParent(
"MemberName", memberPair.first, parentEl);
6773 xmlOut.addTextElementToParent(
6774 "MemberVersion", memberPair.second.toString(), parentEl);
6780 for(
auto& keyInSet : groupInfo.second.keys_)
6782 if(keyInSet == groupKey)
6784 xmlOut.addTextElementToData(
"TableGroupName", groupName);
6785 xmlOut.addTextElementToData(
"TableGroupKey", keyInSet.toString());
6788 xmlOut.addTextElementToData(
"TableGroupType",
6789 groupInfo.second.latestKeyGroupTypeString_);
6790 xmlOut.addTextElementToData(
"TableGroupComment",
6791 groupInfo.second.latestKeyGroupComment_);
6792 xmlOut.addTextElementToData(
"TableGroupAuthor",
6793 groupInfo.second.latestKeyGroupAuthor_);
6794 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6795 groupInfo.second.latestKeyGroupCreationTime_);
6799 xmlOut.addTextElementToData(
"TableGroupMembers",
"");
6802 bool loadingHistoricalInfo =
false;
6803 if(loadingHistoricalInfo)
6808 cfgMgr->loadTableGroup(groupName,
6822 groupTypeString =
"Invalid";
6824 <<
"Failed to load group '" << groupName <<
"(" << keyInSet
6825 <<
")' to extract group comment and type." << __E__;
6828 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
6829 xmlOut.addTextElementToData(
"TableGroupComment", groupComment);
6830 xmlOut.addTextElementToData(
"TableGroupAuthor", groupAuthor);
6831 xmlOut.addTextElementToData(
"TableGroupCreationTime",
6852 void ConfigurationGUISupervisor::handleTablesXML(HttpXmlDocument& xmlOut,
6853 ConfigurationManagerRW* cfgMgr,
6854 bool allowIllegalColumns)
6856 DOMElement* parentEl;
6858 std::string accumulatedErrors =
"";
6859 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
6860 allowIllegalColumns,
6861 allowIllegalColumns ? &accumulatedErrors
6863 std::map<std::string, TableInfo>::const_iterator it = allTableInfo.begin();
6865 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
6867 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
6868 cfgMgr->getVersionAliases();
6870 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
6872 while(it != allTableInfo.end())
6881 xmlOut.addTextElementToData(
"TableName", it->first);
6882 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6885 if(versionAliases.find(it->first) != versionAliases.end())
6886 for(
auto& aliasVersion : versionAliases[it->first])
6887 if(it->second.versions_.find(aliasVersion.second) !=
6888 it->second.versions_.end())
6892 xmlOut.addTextElementToParent(
6894 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
6912 for(
auto& version : it->second.versions_)
6913 if(!version.isScratchVersion())
6914 xmlOut.addTextElementToParent(
"Version", version.toString(), parentEl);
6919 if(accumulatedErrors !=
"")
6920 xmlOut.addTextElementToData(
6922 std::string(
"Column errors were allowed for this request, ") +
6923 "but please note the following errors:\n" + accumulatedErrors);
6929 void ConfigurationGUISupervisor::testXDAQContext()
6933 __SUP_COUT__ <<
"Attempting test activation of the context group." << __E__;
6934 ConfigurationManager cfgMgr;
6936 catch(
const std::runtime_error& e)
6939 <<
"The test activation of the context group failed. Ignoring error: \n"
6940 << e.what() << __E__;
6944 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)