00001 #include "otsdaq-utilities/MacroMaker/MacroMakerSupervisor.h"
00002
00003
00004
00005
00006
00007
00008
00009 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
00010 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00011
00012
00013
00014 #include "otsdaq-core/FECore/FEVInterface.h"
00015
00016
00017 #include "otsdaq-core/CodeEditor/CodeEditor.h"
00018
00019
00020
00021
00022
00023 #include <fstream>
00024
00025 #include <cstdio>
00026 #include <stdio.h>
00027 #include <dirent.h>
00028 #include <sys/stat.h>
00029 #include <thread>
00030
00031 #define MACROS_DB_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroData/"
00032 #define MACROS_HIST_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroHistory/"
00033 #define MACROS_EXPORT_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/MacroExport/"
00034
00035 using namespace ots;
00036
00037 #undef __MF_SUBJECT__
00038 #define __MF_SUBJECT__ "MacroMaker"
00039
00040 XDAQ_INSTANTIATOR_IMPL(MacroMakerSupervisor)
00041
00042
00043 MacroMakerSupervisor::MacroMakerSupervisor(xdaq::ApplicationStub* stub)
00044 : CoreSupervisorBase(stub)
00045 {
00046 INIT_MF("MacroMaker");
00047
00048
00049 mkdir(((std::string)MACROS_DB_PATH).c_str(), 0755);
00050 mkdir(((std::string)MACROS_HIST_PATH).c_str(), 0755);
00051 mkdir(((std::string)MACROS_EXPORT_PATH).c_str(), 0755);
00052
00053 xoap::bind(this, &MacroMakerSupervisor::frontEndCommunicationRequest,
00054 "FECommunication", XDAQ_NS_URI );
00055
00056 init();
00057 }
00058
00059
00060 MacroMakerSupervisor::~MacroMakerSupervisor(void)
00061 {
00062 destroy();
00063 }
00064
00065
00066 void MacroMakerSupervisor::init(void)
00067 {
00068
00069
00070
00071 allFESupervisorInfo_ = allSupervisorInfo_.getAllFETypeSupervisorInfo();
00072 }
00073
00074
00075 void MacroMakerSupervisor::destroy(void)
00076 {
00077
00078 }
00079
00080
00081
00082
00083 void MacroMakerSupervisor::forceSupervisorPropertyValues()
00084 {
00085
00086
00087 }
00088
00089
00090 void MacroMakerSupervisor::request(const std::string& requestType, cgicc::Cgicc& cgiIn,
00091 HttpXmlDocument& xmlOut, const WebUsers::RequestUserInfo& userInfo)
00092 try
00093 {
00094 __SUP_COUT__ << "User name is " << userInfo.username_ << "." << __E__;
00095 __SUP_COUT__ << "User permission level for request '" << requestType << "' is " <<
00096 unsigned(userInfo.permissionLevel_) << "." << __E__;
00097
00098
00099
00100 if(requestType == "getPermission")
00101 {
00102 xmlOut.addTextElementToData("Permission", std::to_string(unsigned(userInfo.permissionLevel_)));
00103
00104
00105 std::string macroPath = (std::string)MACROS_DB_PATH + userInfo.username_ + "/";
00106 mkdir(macroPath.c_str(), 0755);
00107 std::string histPath = (std::string)MACROS_HIST_PATH + userInfo.username_ + "/";
00108 mkdir(histPath.c_str(), 0755);
00109 std::string publicPath = (std::string)MACROS_DB_PATH + "publicMacros/";
00110 mkdir(publicPath.c_str(), 0755);
00111 std::string exportPath = (std::string)MACROS_EXPORT_PATH + userInfo.username_ + "/";
00112 mkdir(exportPath.c_str(), 0755);
00113 }
00114 else
00115 handleRequest(requestType,xmlOut,cgiIn,userInfo.username_);
00116 }
00117 catch(const std::runtime_error& e)
00118 {
00119 __SS__ << "Error occurred handling request '" << requestType <<
00120 "': " << e.what() << __E__;
00121 __SUP_COUT__ << ss.str();
00122 xmlOut.addTextElementToData("Error",ss.str());
00123 }
00124 catch(...)
00125 {
00126 __SS__ << "Unknown error occurred handling request '" << requestType <<
00127 "!'" << __E__;
00128 __SUP_COUT__ << ss.str();
00129 xmlOut.addTextElementToData("Error",ss.str());
00130 }
00131
00132
00133 void MacroMakerSupervisor::handleRequest(const std::string Command,
00134 HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi,
00135 const std::string &username)
00136 {
00137 if(Command == "FElist")
00138 getFElist(xmldoc);
00139 else if(Command == "writeData")
00140 writeData(xmldoc,cgi,username);
00141 else if(Command == "readData")
00142 readData(xmldoc,cgi,username);
00143 else if(Command == "createMacro")
00144 createMacro(xmldoc,cgi,username);
00145 else if(Command == "loadMacros")
00146 loadMacros(xmldoc,username);
00147 else if(Command == "loadHistory")
00148 loadHistory(xmldoc,username);
00149 else if(Command == "deleteMacro")
00150 deleteMacro(xmldoc,cgi,username);
00151 else if(Command == "editMacro")
00152 editMacro(xmldoc,cgi,username);
00153 else if(Command == "clearHistory")
00154 clearHistory(username);
00155 else if(Command == "exportMacro")
00156 exportMacro(xmldoc,cgi,username);
00157 else if(Command == "exportFEMacro")
00158 exportFEMacro(xmldoc,cgi,username);
00159 else if(Command == "getFEMacroList")
00160 getFEMacroList(xmldoc,username);
00161 else if(Command == "runFEMacro")
00162 runFEMacro(xmldoc,cgi);
00163 else
00164 xmldoc.addTextElementToData("Error","Unrecognized command '" + Command + "'");
00165 }
00166
00167
00168
00169 xoap::MessageReference MacroMakerSupervisor::frontEndCommunicationRequest(xoap::MessageReference message)
00170 try
00171 {
00172 __SUP_COUT__<< "FE Request received: " << SOAPUtilities::translate(message) << __E__;
00173
00174 SOAPParameters typeParameter, rxParameters;
00175 typeParameter.addParameter("type");
00176 SOAPUtilities::receive(message, typeParameter);
00177
00178 std::string type = typeParameter.getValue("type");
00179
00180 std::string error = "";
00181
00182
00183 if(type == "initFElist")
00184 {
00185 __SUP_COUTV__(type);
00186
00187 rxParameters.addParameter("groupName");
00188 rxParameters.addParameter("groupKey");
00189 SOAPUtilities::receive(message, rxParameters);
00190
00191 std::string groupName = rxParameters.getValue("groupName");
00192 std::string groupKey = rxParameters.getValue("groupKey");
00193
00194 __SUP_COUTV__(groupName);
00195 __SUP_COUTV__(groupKey);
00196
00197 ConfigurationManager cfgMgr;
00198 cfgMgr.loadConfigurationGroup(
00199 groupName, ConfigurationGroupKey(groupKey), true);
00200
00201
00202
00203
00204 const SupervisorInfoMap& feTypeSupervisors =
00205 CorePropertySupervisorBase::allSupervisorInfo_.getAllFETypeSupervisorInfo();
00206
00207 ConfigurationTree appsNode =
00208 cfgMgr.getNode("XDAQApplicationConfiguration");
00209
00210 for(auto& feApp:feTypeSupervisors)
00211 {
00212 __SUP_COUT__ << "FEs for app " << feApp.first << ":" <<
00213 feApp.second.getName() << __E__;
00214
00215 std::vector<std::string> feChildren =
00216 appsNode.getNode(feApp.second.getName()).
00217 getNode("LinkToSupervisorTable").
00218 getNode("LinkToFEInterfaceTable").getChildrenNames();
00219
00220 for(auto& fe:feChildren)
00221 {
00222 __COUTV__(fe);
00223 FEtoSupervisorMap_[fe] = feApp.first;
00224 }
00225 }
00226
00227 __SUP_COUTV__(StringMacros::mapToString(FEtoSupervisorMap_));
00228 }
00229 else if(type == "feSend" ||
00230 type == "feMacro" ||
00231 type == "feMacroMultiDimensionalStart" ||
00232 type == "feMacroMultiDimensionalCheck" ||
00233 type == "macroMultiDimensionalStart" ||
00234 type == "macroMultiDimensionalCheck")
00235 {
00236 __SUP_COUTV__(type);
00237
00238 rxParameters.addParameter("targetInterfaceID");
00239 SOAPUtilities::receive(message, rxParameters);
00240
00241 std::string targetInterfaceID = rxParameters.getValue("targetInterfaceID");
00242
00243 __SUP_COUTV__(targetInterfaceID);
00244
00245 auto feIt = FEtoSupervisorMap_.find(targetInterfaceID);
00246 if(feIt == FEtoSupervisorMap_.end())
00247 {
00248 __SUP_SS__ << "Destination front end interface ID '" <<
00249 targetInterfaceID << "' was not found in the list of front ends." << __E__;
00250 __SUP_SS_THROW__;
00251 }
00252
00253 unsigned int FESupervisorIndex = feIt->second;
00254 __SUP_COUT__ << "Found supervisor index: " << FESupervisorIndex << __E__;
00255
00256 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
00257 if (it == allFESupervisorInfo_.end())
00258 {
00259 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00260 targetInterfaceID << ":" << FESupervisorIndex << ".' \n\n" <<
00261 "The FE Supervisor Index does not exist. Have you configured the state machine properly?" << __E__;
00262 __SUP_SS_THROW__;
00263 }
00264
00265 if(type == "macroMultiDimensionalStart")
00266 {
00267
00268
00269
00270 SOAPParameters rxParameters;
00271 rxParameters.addParameter("macroName");
00272 SOAPUtilities::receive(message, rxParameters);
00273 std::string macroName = rxParameters.getValue("macroName");
00274 __SUP_COUTV__(macroName);
00275
00276
00277 std::string macroString;
00278 loadMacro(macroName,macroString);
00279
00280 SOAPParameters parameters;
00281 parameters.addParameter("macroString", macroString);
00282 SOAPUtilities::addParameters(message, parameters);
00283 }
00284
00285
00286 try
00287 {
00288 __SUP_COUT__ << "Forwarding request: " <<
00289 SOAPUtilities::translate(message) << __E__;
00290
00291 xoap::MessageReference replyMessage = SOAPMessenger::sendWithSOAPReply(
00292 it->second.getDescriptor(),
00293 message);
00294
00295 if(type != "feSend")
00296 {
00297 __SUP_COUT__ << "Forwarding FE Macro response: " <<
00298 SOAPUtilities::translate(replyMessage) << __E__;
00299
00300 return replyMessage;
00301 }
00302 }
00303 catch(const xdaq::exception::Exception& e)
00304 {
00305 __SUP_SS__ << "Error forwarding FE Communication request to FE Supervisor '" <<
00306 targetInterfaceID << ":" << FESupervisorIndex << ".' " <<
00307 "Have you configured the state machine properly?\n\n" <<
00308 e.what() << __E__;
00309 __SUP_SS_THROW__;
00310 }
00311 }
00312 else
00313 {
00314 __SUP_SS__ << "Unrecognized FE Communication type: " << type << __E__;
00315 __SUP_SS_THROW__;
00316 }
00317
00318 return SOAPUtilities::makeSOAPMessageReference("Received");
00319 }
00320 catch(const std::runtime_error& e)
00321 {
00322 xoap::MessageReference returnMessage =
00323 SOAPUtilities::makeSOAPMessageReference("Error");
00324
00325 SOAPParameters parameters;
00326 parameters.addParameter("Error", e.what());
00327 SOAPUtilities::addParameters(returnMessage, parameters);
00328 return returnMessage;
00329 }
00330 catch(...)
00331 {
00332 xoap::MessageReference returnMessage =
00333 SOAPUtilities::makeSOAPMessageReference("Error");
00334
00335 __SUP_SS__ << "Unknown error processing FE communication request." << __E__;
00336 __SUP_COUT_ERR__ << ss.str();
00337
00338 SOAPParameters parameters;
00339 parameters.addParameter("Error", ss.str());
00340 SOAPUtilities::addParameters(returnMessage, parameters);
00341 return returnMessage;
00342 }
00343
00344
00345 void MacroMakerSupervisor::getFElist(HttpXmlDocument& xmldoc)
00346 {
00347 __SUP_COUT__<< "Getting FE list!!!!!!!!!" << __E__;
00348 FEtoSupervisorMap_.clear();
00349
00350 SOAPParameters txParameters;
00351 txParameters.addParameter("Request", "GetInterfaces");
00352
00353 SOAPParameters rxParameters;
00354 rxParameters.addParameter("FEList");
00355
00356 SupervisorInfoMap::const_iterator it;
00357 std::string oneInterface;
00358 std::string rxFEList;
00359
00360 size_t lastColonIndex;
00361
00362
00363
00364 for(auto &appInfo:allFESupervisorInfo_)
00365 {
00366
00367
00368
00369
00370
00371
00372 __SUP_COUT__ << "FESupervisor LID = " << appInfo.second.getId() <<
00373 " name = " << appInfo.second.getName() << __E__;
00374
00375 try
00376 {
00377 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
00378 appInfo.second.getDescriptor(),
00379 "MacroMakerSupervisorRequest",
00380 txParameters);
00381 SOAPUtilities::receive(retMsg, rxParameters);
00382 }
00383 catch(const xdaq::exception::Exception& e)
00384 {
00385 __SS__ << "Error transmitting request to FE Supervisor LID = " << appInfo.second.getId() <<
00386 " name = " << appInfo.second.getName() << ". \n\n" << e.what() << __E__;
00387 __SUP_COUT_ERR__ << ss.str();
00388 return;
00389 }
00390
00391 rxFEList = rxParameters.getValue("FEList");
00392
00393 __SUP_COUT__ << "FE List received: \n" << rxFEList << __E__;
00394
00395 std::istringstream allInterfaces(rxFEList);
00396 while (std::getline(allInterfaces, oneInterface))
00397 {
00398 __SUP_COUTV__(oneInterface);
00399 xmldoc.addTextElementToData("FE",oneInterface);
00400
00401 lastColonIndex = oneInterface.rfind(':');
00402 if(lastColonIndex == std::string::npos)
00403 {
00404 __SUP_SS__ << "Last colon could not be found in " << oneInterface << __E__;
00405 __SS_THROW__;
00406 }
00407 oneInterface = oneInterface.substr(lastColonIndex);
00408
00409 __SUP_COUTV__(oneInterface);
00410
00411 FEtoSupervisorMap_[oneInterface] = appInfo.second.getId();
00412 }
00413
00414 }
00415
00416 }
00417
00418
00419
00420 void MacroMakerSupervisor::writeData(
00421 HttpXmlDocument& xmldoc,
00422 cgicc::Cgicc& cgi,
00423 const std::string &username)
00424 {
00425 __SUP_COUT__<< "MacroMaker writing..." << __E__;
00426
00427 std::string Address = CgiDataUtilities::getData(cgi, "Address");
00428 std::string Data = CgiDataUtilities::getData(cgi, "Data");
00429 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi, "interfaceIndex");
00430 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi, "supervisorIndex");
00431 std::string time = CgiDataUtilities::decodeURIComponent(
00432 CgiDataUtilities::getData(cgi, "time"));
00433 std::string addressFormatStr = CgiDataUtilities::getData(cgi, "addressFormatStr");
00434 std::string dataFormatStr = CgiDataUtilities::getData(cgi, "dataFormatStr");
00435
00436 std::string interfaces = CgiDataUtilities::postData(cgi, "interfaces");
00437
00438 __SUP_COUT__<< "Write Address: " << Address << " Data: " << Data << __E__;
00439 __SUP_COUTV__(interfaces);
00440
00441 std::string command = "w:" + Address + ":" + Data;
00442 std::string format = addressFormatStr + ":" + dataFormatStr;
00443 appendCommandToHistory(command,format,time,interfaces,username);
00444
00445 SOAPParameters txParameters;
00446 txParameters.addParameter("Request", "UniversalWrite");
00447 txParameters.addParameter("Address",Address);
00448 txParameters.addParameter("Data",Data);
00449
00450
00451 __SUP_COUT__<< "Here comes the array from multiselect box for WRITE, behold: \n"
00452 << supervisorIndexArray << "\n" << interfaceIndexArray << __E__;
00453
00455 std::vector<std::string> interfaceIndices;
00456 std::istringstream f(interfaceIndexArray);
00457 std::string s;
00458 while (getline(f, s, ',')) interfaceIndices.push_back(s);
00459 std::vector<int> supervisorIndices;
00460 std::istringstream g(supervisorIndexArray);
00461 std::string t;
00462 while (getline(g, t, ',')) supervisorIndices.push_back(std::stoi(t));
00463
00464
00465 for(unsigned int i=0; i < supervisorIndices.size(); i++)
00466 {
00467 unsigned int FESupervisorIndex = supervisorIndices[i];
00468 std::string interfaceIndex = interfaceIndices[i];
00469
00470 txParameters.addParameter("InterfaceID",interfaceIndex);
00471
00472 __SUP_COUT__<< "The index of the supervisor instance is: " << FESupervisorIndex << __E__;
00473 __SUP_COUT__<< "...and the interface ID is: " << interfaceIndex << __E__;
00474
00475 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
00476 if (it == allFESupervisorInfo_.end())
00477 {
00478 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00479 interfaceIndex << ":" << FESupervisorIndex << ".' \n\n" <<
00480 "The FE Index doesn't exist. Have you configured the state machine properly?" << __E__;
00481 __SUP_SS_THROW__;
00482 }
00483
00484 try
00485 {
00486 xoap::MessageReference replyMessage = SOAPMessenger::sendWithSOAPReply(
00487 it->second.getDescriptor(),
00488 "MacroMakerSupervisorRequest",
00489 txParameters);
00490
00491 __SUP_COUT__ << "Response received: " <<
00492 SOAPUtilities::translate(replyMessage) << __E__;
00493
00494 SOAPParameters rxParameters;
00495 rxParameters.addParameter("Error");
00496 SOAPUtilities::receive(replyMessage,rxParameters);
00497
00498 std::string error = rxParameters.getValue("Error");
00499 __SUP_COUTV__(error);
00500
00501 if(error != "")
00502 {
00503
00504 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00505 interfaceIndex << ":" << FESupervisorIndex << ".' " <<
00506 "Have you configured the state machine properly?\n\n" <<
00507 error << __E__;
00508 __SUP_SS_THROW__;
00509 }
00510 }
00511 catch(const xdaq::exception::Exception& e)
00512 {
00513 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00514 interfaceIndex << ":" << FESupervisorIndex << ".' " <<
00515 "Have you configured the state machine properly?\n\n" <<
00516 e.what() << __E__;
00517 __SUP_SS_THROW__;
00518 }
00519
00520
00521 }
00522 }
00523
00524
00525 void MacroMakerSupervisor::readData(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi, const std::string &username)
00526 {
00527 __SUP_COUT__<< "@@@@@@@ MacroMaker wants to read data @@@@@@@@" << __E__;
00528 std::string Address = CgiDataUtilities::getData(cgi, "Address");
00529 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi, "interfaceIndex");
00530 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi, "supervisorIndex");
00531 std::string time = CgiDataUtilities::decodeURIComponent(
00532 CgiDataUtilities::getData(cgi, "time"));
00533 std::string addressFormatStr = CgiDataUtilities::getData(cgi, "addressFormatStr");
00534 std::string dataFormatStr = CgiDataUtilities::getData(cgi, "dataFormatStr");
00535
00536 std::string interfaces = CgiDataUtilities::postData(cgi, "interfaces");
00537
00538
00539 __SUP_COUT__<< "Read Address: " << Address << __E__;
00540 __SUP_COUTV__(interfaces);
00541
00542 SOAPParameters txParameters;
00543 txParameters.addParameter("Request", "UniversalRead");
00544 txParameters.addParameter("Address",Address);
00545
00546 SOAPParameters rxParameters;
00547 rxParameters.addParameter("dataResult");
00548 rxParameters.addParameter("Error");
00549 __SUP_COUT__<< "Here comes the array from multiselect box for READ, behold: "
00550 << supervisorIndexArray << "," << interfaceIndexArray << __E__;
00551
00552
00554 std::vector<std::string> interfaceIndices;
00555 std::istringstream f(interfaceIndexArray);
00556 std::string s;
00557 while (getline(f, s, ',')) interfaceIndices.push_back(s);
00558 std::vector<int> supervisorIndices;
00559 std::istringstream g(supervisorIndexArray);
00560 std::string t;
00561 while (getline(g, t, ',')) supervisorIndices.push_back(std::stoi(t));
00562
00563 for(unsigned int i=0; i < supervisorIndices.size(); i++)
00564 {
00565 unsigned int FESupervisorIndex = supervisorIndices[i];
00566 std::string interfaceIndex = interfaceIndices[i];
00567
00568 txParameters.addParameter("InterfaceID",interfaceIndex);
00569
00570
00571 __SUP_COUT__ << "The index of the supervisor instance is: " << FESupervisorIndex << __E__;
00572 __SUP_COUT__ << "...and the interface ID is: " << interfaceIndex << __E__;
00573
00574 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
00575 if (it == allFESupervisorInfo_.end())
00576 {
00577 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00578 interfaceIndex << ":" << FESupervisorIndex << ".' \n\n" <<
00579 "The FE Index doesn't exist. Have you configured the state machine properly?" << __E__;
00580 __SUP_SS_THROW__;
00581 }
00582
00583 try
00584 {
00585 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
00586 it->second.getDescriptor(),
00587 "MacroMakerSupervisorRequest",
00588 txParameters);
00589
00590 __SUP_COUT__ << "Response received: " <<
00591 SOAPUtilities::translate(retMsg) << __E__;
00592
00593
00594
00595 SOAPUtilities::receive(retMsg,rxParameters);
00596
00597 std::string error = rxParameters.getValue("Error");
00598 __SUP_COUTV__(error);
00599
00600 if(error != "")
00601 {
00602
00603 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00604 interfaceIndex << ":" << FESupervisorIndex << ".' " <<
00605 "Have you configured the state machine properly?\n\n" <<
00606 error << __E__;
00607 __SUP_SS_THROW__;
00608 }
00609 }
00610 catch(const xdaq::exception::Exception& e)
00611 {
00612 __SUP_SS__ << "Error transmitting request to FE Supervisor '" <<
00613 interfaceIndex << ":" << FESupervisorIndex << ".' " <<
00614 "Have you configured the state machine properly?\n\n" <<
00615 e.what() << __E__;
00616 __SUP_SS_THROW__;
00617 }
00618
00619 std::string dataReadResult = rxParameters.getValue("dataResult");
00620 __SUP_COUT__<< "Data reading result received: " << dataReadResult << __E__;
00621 xmldoc.addTextElementToData("readData",dataReadResult);
00622 std::string command = "r:" + Address + ":" + dataReadResult;
00623 std::string format = addressFormatStr + ":" + dataFormatStr;
00624 appendCommandToHistory(command,format,time,interfaces,username);
00625 }
00626 }
00627
00628
00629 void MacroMakerSupervisor::createMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi, const std::string &username)
00630 {
00631 __SUP_COUT__<< "MacroMaker wants to create a macro!!!!!!!!!" << __E__;
00632 std::string Name = CgiDataUtilities::postData(cgi, "Name");
00633 std::string Sequence = CgiDataUtilities::postData(cgi, "Sequence");
00634 std::string Time = CgiDataUtilities::postData(cgi, "Time");
00635 std::string Notes = CgiDataUtilities::decodeURIComponent(
00636 CgiDataUtilities::postData(cgi, "Notes"));
00637 std::string isMacroPublic = CgiDataUtilities::getData(cgi, "isPublic");
00638 std::string isMacroLSBF = CgiDataUtilities::getData(cgi, "isLSBF");
00639
00640 __SUP_COUTV__(Name);
00641 __SUP_COUTV__(Sequence);
00642 __SUP_COUTV__(Notes);
00643 __SUP_COUTV__(Time);
00644 __SUP_COUTV__(isMacroPublic);
00645 __SUP_COUTV__(isMacroLSBF);
00646
00647 __SUP_COUTV__(MACROS_DB_PATH);
00648
00649 std::string fileName = Name + ".dat";
00650 std::string fullPath;
00651 if (isMacroPublic == "true") fullPath = (std::string)MACROS_DB_PATH + "publicMacros/" + fileName;
00652 else fullPath = (std::string)MACROS_DB_PATH + username + "/" + fileName;
00653
00654 __SUP_COUTV__(fullPath);
00655
00656 std::ofstream macrofile (fullPath.c_str());
00657 if (macrofile.is_open())
00658 {
00659 macrofile << "{\n";
00660 macrofile << "\"name\":\"" << Name << "\",\n";
00661 macrofile << "\"sequence\":\"" << Sequence << "\",\n";
00662 macrofile << "\"time\":\"" << Time << "\",\n";
00663 macrofile << "\"notes\":\"" << Notes << "\",\n";
00664 macrofile << "\"LSBF\":\"" << isMacroLSBF << "\"\n";
00665 macrofile << "}@" << __E__;
00666 macrofile.close();
00667 }
00668 else
00669 __SUP_COUT__<< "Unable to open file" << __E__;
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 void MacroMakerSupervisor::loadMacro(
00681 const std::string& macroName,
00682 std::string& macroString,
00683 const std::string &username )
00684 {
00685 __SUP_COUTV__(macroName);
00686
00687
00688 std::string fullPath, line;
00689 macroString = "";
00690 for(unsigned int i=0;i<2;++i)
00691 {
00692 if(i == 1)
00693 fullPath = (std::string)MACROS_DB_PATH + username + "/";
00694 else
00695 fullPath = (std::string)MACROS_DB_PATH + "publicMacros/";
00696
00697 fullPath += macroName + ".dat";
00698 __SUP_COUTV__(fullPath);
00699
00700 std::ifstream read (fullPath.c_str());
00701 if (read.is_open())
00702 {
00703 while (! read.eof() )
00704 {
00705 getline (read,line);
00706 macroString += line;
00707 }
00708
00709 read.close();
00710 }
00711 else
00712 {
00713 __SUP_COUT__<< "Unable to open file: " << fullPath << __E__;
00714 continue;
00715 }
00716
00717 if(macroString != "") break;
00718 }
00719
00720 if(macroString == "")
00721 {
00722 __SUP_SS__<< "Unable to locate file for macro '" << macroName <<
00723 "'... does it exist?" << __E__;
00724 if(username != "")
00725 ss << " Attempted username was '" << username << ".'" << __E__;
00726 __SUP_SS_THROW__;
00727 }
00728
00729 __SUP_COUTV__(macroString);
00730 }
00731
00732
00733 void MacroMakerSupervisor::loadMacros(HttpXmlDocument& xmldoc, const std::string &username)
00734 {
00735 DIR *dir;
00736 struct dirent *ent;
00737 std::string returnStr = "";
00738 std::string fullPath = (std::string)MACROS_DB_PATH + username + "/";
00739 if ((dir = opendir (fullPath.c_str())) != NULL)
00740 {
00741
00742 while ((ent = readdir (dir)) != NULL)
00743 {
00744
00745 if ((unsigned)strlen(ent->d_name) > 4)
00746 {
00747 std::string line;
00748 std::ifstream read (((fullPath + (std::string)ent->d_name)).c_str());
00749 if (read.is_open())
00750 {
00751 std::stringstream buffer;
00752 while (! read.eof() )
00753 {
00754 getline (read,line);
00755 buffer << line;
00756
00757 }
00758 returnStr += buffer.str();
00759
00760 read.close();
00761 }
00762 else
00763 __SUP_COUT__<< "Unable to open file" << __E__;
00764 }
00765 }
00766 std::string returnMacroStr = returnStr.substr(0, returnStr.size()-1);
00767
00768 __SUP_COUT__<< "Loading existing macros! " << returnMacroStr << __E__;
00769
00770 closedir (dir);
00771 xmldoc.addTextElementToData("returnMacroStr",returnMacroStr);
00772 }
00773 else
00774 {
00775 __SUP_COUT__<< "Looping through privateMacros folder failed! Wrong directory" << __E__;
00776 }
00777 fullPath = (std::string)MACROS_DB_PATH + "publicMacros/";
00778 returnStr = "";
00779 if ((dir = opendir (fullPath.c_str())) != NULL)
00780 {
00781
00782 while ((ent = readdir (dir)) != NULL)
00783 {
00784
00785 if ((unsigned)strlen(ent->d_name) > 4)
00786 {
00787 std::string line;
00788 std::ifstream read (((fullPath + (std::string)ent->d_name)).c_str());
00789 if (read.is_open())
00790 {
00791 std::stringstream buffer;
00792 while (! read.eof() )
00793 {
00794 getline (read,line);
00795 buffer << line;
00796
00797 }
00798 returnStr += buffer.str();
00799 read.close();
00800 }
00801 else
00802 __SUP_COUT__<< "Unable to open file" << __E__;
00803 }
00804 }
00805 std::string returnPublicStr = returnStr.substr(0, returnStr.size()-1);
00806 __SUP_COUT__<< "Loading existing public macros: " << returnPublicStr << __E__;
00807 closedir (dir);
00808 xmldoc.addTextElementToData("returnPublicStr",returnPublicStr);
00809 }
00810 else
00811 {
00812 __SUP_COUT__ << fullPath << __E__;
00813 __SUP_COUT__<< "Looping through MacroData folder failed! Wrong directory" << __E__;
00814
00815 }
00816 }
00817
00818
00819 void MacroMakerSupervisor::appendCommandToHistory(std::string Command,
00820 std::string Format, std::string Time, std::string Interfaces, const std::string &username)
00821 {
00822 std::string fileName = "history.hist";
00823 std::string fullPath = (std::string)MACROS_HIST_PATH + username + "/" + fileName;
00824 __SUP_COUT__ << fullPath << __E__;
00825 std::ofstream histfile (fullPath.c_str(),std::ios::app);
00826 if (histfile.is_open())
00827 {
00828 histfile << "{\n";
00829 histfile << "\"Command\":\"" << Command << "\",\n";
00830 histfile << "\"Format\":\"" << Format << "\",\n";
00831 histfile << "\"Time\":\"" << Time << "\",\n";
00832 histfile << "\"Interfaces\":\"" << Interfaces << "\"\n";
00833 histfile << "}#" << __E__;
00834 histfile.close();
00835 }
00836 else
00837 __SUP_COUT__<< "Unable to open history.hist" << __E__;
00838 }
00839
00840
00841 void MacroMakerSupervisor::loadHistory(HttpXmlDocument& xmldoc, const std::string &username)
00842 {
00843 std::string fileName = MACROS_HIST_PATH + username + "/" + "history.hist";
00844
00845 std::ifstream read (fileName.c_str());
00846 __SUP_COUT__<< fileName << __E__;
00847
00848 if (read.is_open())
00849 {
00850 std::string line;
00851 char * returnStr;
00852 unsigned long long fileSz, i = 0, MAX_HISTORY_SIZE = 100000;
00853
00854
00855
00856
00857 read.seekg(0, std::ios::end);
00858 fileSz = read.tellg();
00859 returnStr = new char[fileSz+1];
00860 returnStr[fileSz] = '\0';
00861 read.seekg(0, std::ios::beg);
00862
00863
00864
00865 read.read(returnStr,fileSz);
00866 read.close();
00867
00868
00869
00870 if(fileSz > MAX_HISTORY_SIZE)
00871 {
00872 i = fileSz - MAX_HISTORY_SIZE;
00873 for(;i<fileSz;++i)
00874 if(returnStr[i] == '#')
00875 {
00876 i += 2; break;
00877 }
00878 if(i > fileSz) i = fileSz;
00879
00880
00881 FILE *fp = fopen(fileName.c_str(),"w");
00882 if(!fp)
00883 {
00884 __SS__ << "Big problem with macromaker history file: " << fileName << __E__;
00885 __SS_THROW__;
00886 }
00887 fwrite(&returnStr[i],fileSz-i,1,fp);
00888 fclose(fp);
00889 }
00890
00891 __SUP_COUT__<< "Loading user history! " << __E__;
00892
00893 if(fileSz > 1)
00894 returnStr[fileSz-2] = '\0';
00895
00896 xmldoc.addTextElementToData("returnHistStr",&returnStr[i]);
00897
00898
00899 delete[] returnStr;
00900 }
00901 else
00902
00903 __SUP_COUT__<< "Unable to open history.hist" << __E__;
00904
00905 }
00906
00907
00908 void MacroMakerSupervisor::deleteMacro(HttpXmlDocument& xmldoc,cgicc::Cgicc& cgi, const std::string &username)
00909 {
00910 std::string MacroName = CgiDataUtilities::getData(cgi, "MacroName");
00911 std::string isMacroPublic = CgiDataUtilities::getData(cgi, "isPublic");
00912
00913
00914 std::string fileName = MacroName + ".dat";
00915 std::string fullPath;
00916 if (isMacroPublic == "true") fullPath = (std::string)MACROS_DB_PATH + "publicMacros/" + fileName;
00917 else fullPath = (std::string)MACROS_DB_PATH + username + "/" + fileName;
00918
00919 __SUP_COUT__<< fullPath << __E__;
00920
00921 std::remove(fullPath.c_str());
00922 __SUP_COUT__ << "Successfully deleted " << MacroName;
00923 xmldoc.addTextElementToData("deletedMacroName",MacroName);
00924 }
00925
00926
00927 void MacroMakerSupervisor::editMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi, const std::string &username)
00928 {
00929 std::string oldMacroName = CgiDataUtilities::postData(cgi, "oldMacroName");
00930 std::string newMacroName = CgiDataUtilities::postData(cgi, "newMacroName");
00931 std::string Sequence = CgiDataUtilities::postData(cgi, "Sequence");
00932 std::string Time = CgiDataUtilities::postData(cgi, "Time");
00933 std::string Notes = CgiDataUtilities::decodeURIComponent(
00934 CgiDataUtilities::postData(cgi, "Notes"));
00935
00936 std::string isMacroPublic = CgiDataUtilities::getData(cgi, "isPublic");
00937 std::string isMacroLSBF = CgiDataUtilities::getData(cgi, "isLSBF");
00938
00939 __SUP_COUTV__(oldMacroName);
00940 __SUP_COUTV__(newMacroName);
00941 __SUP_COUTV__(Sequence);
00942 __SUP_COUTV__(Notes);
00943 __SUP_COUTV__(Time);
00944 __SUP_COUTV__(isMacroPublic);
00945 __SUP_COUTV__(isMacroLSBF);
00946
00947 __SUP_COUTV__(MACROS_DB_PATH);
00948
00949 std::string fileName = oldMacroName + ".dat";
00950 std::string fullPath;
00951 if (isMacroPublic == "true") fullPath = (std::string)MACROS_DB_PATH + "publicMacros/" + fileName;
00952 else fullPath = (std::string)MACROS_DB_PATH + username + "/" + fileName;
00953
00954 __SUP_COUTV__(fullPath);
00955
00956 std::ofstream macrofile (fullPath.c_str());
00957 if (macrofile.is_open())
00958 {
00959 macrofile << "{\n";
00960 macrofile << "\"name\":\"" << newMacroName << "\",\n";
00961 macrofile << "\"sequence\":\"" << Sequence << "\",\n";
00962 macrofile << "\"time\":\"" << Time << "\",\n";
00963 macrofile << "\"notes\":\"" << Notes << "\",\n";
00964 macrofile << "\"LSBF\":\"" << isMacroLSBF << "\"\n";
00965 macrofile << "}@" << __E__;
00966 macrofile.close();
00967 }
00968 else
00969 __SUP_COUT__<< "Unable to open file" << __E__;
00970
00971 if(oldMacroName != newMacroName)
00972 {
00973 int result;
00974 result = rename((MACROS_DB_PATH + username + "/" + oldMacroName + ".dat").c_str(), (MACROS_DB_PATH + username + "/" + newMacroName + ".dat").c_str());
00975 if (result == 0)
00976 xmldoc.addTextElementToData("newMacroName",newMacroName);
00977 else
00978 xmldoc.addTextElementToData("newMacroName","ERROR");
00979 }
00980 }
00981
00982
00983 void MacroMakerSupervisor::clearHistory(const std::string &username)
00984 {
00985 std::string fileName = "history.hist";
00986 std::string fullPath = (std::string)MACROS_HIST_PATH + username + "/" + fileName;
00987
00988 std::remove(fullPath.c_str());
00989 __SUP_COUT__<< "Successfully deleted " << fullPath;
00990 }
00991
00992
00993 void MacroMakerSupervisor::exportFEMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi,
00994 const std::string &username)
00995 {
00996 std::string macroName = CgiDataUtilities::getData(cgi, "MacroName");
00997 std::string pluginName = CgiDataUtilities::getData(cgi, "PluginName");
00998 std::string macroSequence = CgiDataUtilities::postData(cgi, "MacroSequence");
00999 std::string macroNotes = CgiDataUtilities::decodeURIComponent(
01000 CgiDataUtilities::postData(cgi, "MacroNotes"));
01001
01002 __SUP_COUTV__(pluginName);
01003 __SUP_COUTV__(macroName);
01004 __SUP_COUTV__(macroSequence);
01005
01006
01007 for(unsigned int i=0;i<macroNotes.length();++i)
01008 if(macroNotes[i] == '\r' || macroNotes[i] == '\n')
01009 macroNotes[i] = ' ';
01010 __SUP_COUTV__(macroNotes);
01011
01012 std::stringstream ss(macroSequence);
01013 std::string command;
01014 std::vector<std::string> commands;
01015
01016 while (getline(ss, command, ',')) commands.push_back(command);
01017
01018 __SUP_COUTV__(StringMacros::vectorToString(commands));
01019
01020 std::map<std::string ,std::set<std::string> >
01021 specialsCodeMap = CodeEditor::getSpecialsMap();
01022
01023
01024 auto specialsCodeMapIt = specialsCodeMap.find(CodeEditor::SPECIAL_TYPE_FEInterface);
01025 if(specialsCodeMapIt == specialsCodeMap.end())
01026 {
01027 __SS__ << "Could not find any FE Interface plugins in source code. Does MacroMaker " <<
01028 "have access to the source code? Check that the Supervisor context places MacroMaker in a " <<
01029 "location with access to the source code." << __E__;
01030 __SS_THROW__;
01031 }
01032
01033
01034 std::string headerFile = pluginName + ".h";
01035 std::string sourceFile = pluginName + "_interface.cc";
01036 bool foundHeaderFile = false;
01037 bool foundSourceFile = false;
01038 for(const auto& filePath : specialsCodeMapIt->second)
01039 {
01040 if(!foundHeaderFile &&
01041 filePath.find(headerFile) != std::string::npos)
01042 {
01043 foundHeaderFile = true;
01044 headerFile = filePath;
01045 __SUP_COUT__ << "found headerFile=" << filePath << __E__;
01046 }
01047 if(!foundSourceFile &&
01048 filePath.find(sourceFile) != std::string::npos)
01049 {
01050 foundSourceFile = true;
01051 sourceFile = filePath;
01052 __SUP_COUT__ << "found sourceFile=" << filePath << __E__;
01053 }
01054
01055 if(foundSourceFile && foundHeaderFile) break;
01056 }
01057
01058 if(!foundHeaderFile)
01059 {
01060 __SS__ << "Could not find the header file for the FE Interface plugins at '" <<
01061 headerFile << ".' Does MacroMaker " <<
01062 "have access to the source code? Check that the Supervisor context places MacroMaker in a " <<
01063 "location with access to the source code." << __E__;
01064 __SS_THROW__;
01065 }
01066 if(!foundSourceFile)
01067 {
01068 __SS__ << "Could not find the source file for the FE Interface plugins at '" <<
01069 sourceFile << ".' Does MacroMaker " <<
01070 "have access to the source code? Check that the Supervisor context places MacroMaker in a " <<
01071 "location with access to the source code." << __E__;
01072 __SS_THROW__;
01073 }
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084 char timeBuffer[100];
01085 {
01086 time_t rawtime;
01087 struct tm * timeinfo;
01088
01089 time (&rawtime);
01090 timeinfo = localtime(&rawtime);
01091
01092 strftime(timeBuffer,100,"%b-%d-%Y %I:%M:%S",timeinfo);
01093 }
01094
01095 std::string contents;
01096 std::string insert;
01097
01099
01100 CodeEditor::readFile(sourceFile,contents);
01101
01102
01103
01104 xmldoc.addTextElementToData("sourceFile",sourceFile);
01105 xmldoc.addTextElementToData("headerFile",headerFile);
01106
01107
01108 if(contents.find(pluginName + "::" + macroName) !=
01109 std::string::npos)
01110 {
01111 __SS__ << "The function definition '" << (pluginName + "::" + macroName) <<
01112 "(...)' already exists in the source file '" << sourceFile <<
01113 ".' Duplicate functions are not allowed - please rename the macro or modify the source file." << __E__;
01114 __SS_THROW__;
01115 }
01116
01117
01118
01119 std::stringstream codess;
01120 std::set<std::string> inArgNames, outArgNames;
01121 createCode(codess,commands,"\t" , true ,
01122 &inArgNames,&outArgNames);
01123 __SUP_COUTV__(StringMacros::setToString(inArgNames));
01124 __SUP_COUTV__(StringMacros::setToString(outArgNames));
01125
01126
01127 {
01128 auto insertPos = contents.find(pluginName + "::" + pluginName);
01129 if(insertPos == std::string::npos)
01130 {
01131 __SS__ << "Could not find the code insert position in the source file '" <<
01132 sourceFile << ".' The FE plugin class constructor must be '" <<
01133 pluginName << ":" << pluginName <<"' - is this the case?" << __E__;
01134 __SS_THROW__;
01135 }
01136 __SUP_COUTV__(insertPos);
01137
01138 insertPos = contents.find("{",insertPos);
01139 if(insertPos == std::string::npos)
01140 {
01141 __SS__ << "Could not find the code insert position in the source file '" <<
01142 sourceFile << ".' The FE plugin class constructor must begin with '{" <<
01143 "' - is this the case?" << __E__;
01144 __SS_THROW__;
01145 }
01146 ++insertPos;
01147 __SUP_COUTV__(insertPos);
01148
01149 insert = "\n\t//registration of FEMacro '" + macroName + "' generated, " +
01150 timeBuffer + ", by '" + username + "' using MacroMaker.\n\t" +
01151 "FEVInterface::registerFEMacroFunction(\"" + macroName + "\",//feMacroName \n\t\t" +
01152 "static_cast<FEVInterface::frontEndMacroFunction_t>(&" +
01153 pluginName + "::" + macroName + "), //feMacroFunction \n\t\t" +
01154 "std::vector<std::string>{";
01155 {
01156 bool first = true;
01157 for(const auto& inArg:inArgNames)
01158 {
01159 if(first)
01160 first = false;
01161 else
01162 insert += ",";
01163 insert += "\"" + inArg + "\"";
01164 }
01165 }
01166 insert += "}, //namesOfInputArgs \n\t\t";
01167 insert += "std::vector<std::string>{";
01168 {
01169 bool first = true;
01170 for(const auto& outArg:outArgNames)
01171 {
01172 if(first)
01173 first = false;
01174 else
01175 insert += ",";
01176 insert += "\"" + outArg + "\"";
01177 }
01178 }
01179 insert += "}, //namesOfOutputArgs \n\t\t";
01180 insert += "1); //requiredUserPermissions \n\n";
01181
01182 __SUP_COUTV__(insert);
01183 contents = contents.substr(0,insertPos) + insert + contents.substr(insertPos);
01184 }
01185
01186
01187 {
01188 auto insertPos = contents.rfind("DEFINE_OTS_INTERFACE");
01189 if(insertPos == std::string::npos)
01190 {
01191 __SS__ << "Could not find the code insert position in the source file '" <<
01192 sourceFile << ".' The FE plugin class must end with a 'DEFINE_OTS_INTERFACE(" <<
01193 pluginName << ")' - is this the case?" << __E__;
01194 __SS_THROW__;
01195 }
01196 __SUP_COUTV__(insertPos);
01197
01198 insert = "\n//========================================================================================================================\n//" +
01199 macroName + "\n" +
01200 "//\tFEMacro '" + macroName + "' generated, " +
01201 timeBuffer + ", by '" + username + "' using MacroMaker.\n" +
01202 "//\tMacro Notes: " + macroNotes + "\n" +
01203 "void " + pluginName + "::" + macroName + "(__ARGS__)\n{\n\t" +
01204 "__CFG_COUT__ << \"# of input args = \" << argsIn.size() << __E__; \n\t" +
01205 "__CFG_COUT__ << \"# of output args = \" << argsOut.size() << __E__; \n\t" +
01206 "for(auto &argIn:argsIn) \n\t\t" +
01207 "__CFG_COUT__ << argIn.first << \": \" << argIn.second << __E__; \n\n\t" +
01208 "//macro commands section \n" +
01209 codess.str() +
01210 "\n\n\t" +
01211 "for(auto &argOut:argsOut) \n\t\t" +
01212 "__CFG_COUT__ << argOut.first << \": \" << argOut.second << __E__; \n\n" +
01213 "} //end " + macroName + "()\n\n";
01214
01215
01216 CodeEditor::writeFile(sourceFile,contents,insertPos,insert);
01217 }
01218
01219
01220
01222
01223 CodeEditor::readFile(headerFile,contents);
01224
01225
01226
01227
01228 {
01229 auto insertPos = contents.rfind("};");
01230 if(insertPos == std::string::npos)
01231 {
01232 __SS__ << "Could not find the code insert position in the header file '" <<
01233 headerFile << ".' The FE plugin class must end with a '};' - is this the case?" << __E__;
01234 __SS_THROW__;
01235 }
01236
01237 __SUP_COUTV__(insertPos);
01238
01239 insert = "\npublic: // FEMacro '" + macroName + "' generated, " +
01240 timeBuffer + ", by '" + username + "' using MacroMaker.\n\t" +
01241 "void " + macroName +
01242 "\t(__ARGS__);\n";
01243
01244 __SUP_COUTV__(insert);
01245 CodeEditor::writeFile(headerFile,contents,insertPos,insert);
01246 }
01247
01248
01249 }
01250
01251
01252 void MacroMakerSupervisor::exportMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi, const std::string &username)
01253 {
01254 std::string macroName = CgiDataUtilities::getData(cgi, "MacroName");
01255 std::string macroSequence = CgiDataUtilities::postData(cgi, "MacroSequence");
01256 std::string macroNotes = CgiDataUtilities::decodeURIComponent(
01257 CgiDataUtilities::postData(cgi, "MacroNotes"));
01258
01259 __SUP_COUTV__(macroName);
01260 __SUP_COUTV__(macroSequence);
01261
01262
01263 for(unsigned int i=0;i<macroNotes.length();++i)
01264 if(macroNotes[i] == '\r' || macroNotes[i] == '\n')
01265 macroNotes[i] = ' ';
01266 __SUP_COUTV__(macroNotes);
01267
01268 std::stringstream ss(macroSequence);
01269 std::string command;
01270 std::vector<std::string> commands;
01271
01272 while (getline(ss, command, ',')) commands.push_back(command);
01273
01274 std::string fileName = macroName + ".cc";
01275
01276
01277 std::string fullPath = (std::string)MACROS_EXPORT_PATH + username + "/" + fileName;
01278 __SUP_COUT__ << fullPath << __E__;
01279 std::ofstream exportFile (fullPath.c_str(),std::ios::trunc);
01280 if (exportFile.is_open())
01281 {
01282 exportFile << "//Generated Macro Name:\t" << macroName << "\n";
01283 exportFile << "//Macro Notes: " << macroNotes << "\n";
01284
01285 {
01286 time_t rawtime;
01287 struct tm * timeinfo;
01288 char buffer[100];
01289
01290 time (&rawtime);
01291 timeinfo = localtime(&rawtime);
01292
01293 strftime(buffer,100,"%b-%d-%Y %I:%M:%S",timeinfo);
01294 exportFile << "//Generated Time: \t\t" << buffer << "\n";
01295 }
01296
01297 exportFile << "//Paste this whole file into an interface to transfer Macro functionality.\n";
01298
01299 createCode(exportFile,commands);
01300
01301 exportFile.close();
01302
01303 xmldoc.addTextElementToData("ExportFile",fullPath);
01304 }
01305 else
01306 __SUP_COUT__ << "Unable to open file" << __E__;
01307 }
01308
01309
01310
01311
01312 void MacroMakerSupervisor::createCode(std::ostream& out,
01313 const std::vector<std::string>& commands,
01314 const std::string& tabOffset,
01315 bool forFeMacro,
01316 std::set<std::string>* inArgNames,
01317 std::set<std::string>* outArgNames)
01318 {
01319 int numOfHexBytes;
01320 std::set<std::string > argInHasBeenInitializedSet;
01321 bool addressIsVariable, dataIsVariable;
01322
01323 out << tabOffset << "{";
01324
01325 out << "\n" << tabOffset << "\t" << "char *address \t= new char[universalAddressSize_]{0}; //create address buffer of interface size and init to all 0";
01326 out << "\n" << tabOffset << "\t" << "char *data \t\t= new char[universalDataSize_]{0}; //create data buffer of interface size and init to all 0";
01327
01328 out << "\n" << tabOffset << "\t" << "uint64_t macroAddress; //create macro address buffer (size 8 bytes)";
01329 out << "\n" << tabOffset << "\t" << "uint64_t macroData; //create macro address buffer (size 8 bytes)";
01330
01331 out << "\n" << tabOffset << "\t" << "std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create map from arg name to 64-bit number";
01332
01333
01334 for(unsigned int i = 0; i < commands.size(); i++)
01335 {
01336 std::stringstream sst(commands[i]);
01337 std::string tokens;
01338 std::vector<std::string> oneCommand;
01339 while (getline(sst, tokens, ':')) oneCommand.push_back(tokens);
01340 while(oneCommand.size() < 4) oneCommand.push_back("");
01341
01342 __SUP_COUTV__(StringMacros::vectorToString(oneCommand));
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367 addressIsVariable = isArgumentVariable(oneCommand[2]);
01368 dataIsVariable = isArgumentVariable(oneCommand[3]);
01369
01370 __SUP_COUTV__(addressIsVariable);
01371 __SUP_COUTV__(dataIsVariable);
01372
01373 out << "\n\n" << tabOffset << "\t// command-#" << i << ": ";
01374
01375 if(oneCommand[1][0] == 'w' || oneCommand[1][0] == 'r')
01376 {
01377 if (oneCommand[1][0] == 'w')
01378 out << "Write(";
01379 else if (oneCommand[1][0] == 'r')
01380 out << "Read(";
01381
01382 if(addressIsVariable)
01383 out << oneCommand[2];
01384 else
01385 out << "0x" << oneCommand[2];
01386 out << " /*address*/,";
01387
01388 if(dataIsVariable)
01389 out << oneCommand[3] << " /*data*/";
01390 else if (oneCommand[1][0] == 'w')
01391 out << "0x" << oneCommand[3] << " /*data*/";
01392 else if (oneCommand[1][0] == 'r')
01393 out << "data";
01394 out << ");\n";
01395 }
01396 else if (oneCommand[1][0] == 'd')
01397 {
01398 out << "delay(" << oneCommand[2] << ");\n";
01399 out << tabOffset << "\t" << "__CFG_COUT__ << \"Sleeping for... \" << " << oneCommand[2] <<
01400 " << \" milliseconds \" << __E__;\n";
01401 out << tabOffset << "\t" << "usleep(" << oneCommand[2] << "*1000 /* microseconds */);\n";
01402 continue;
01403 }
01404 else
01405 {
01406 __SS__ << "FATAL ERROR: Unknown command '" << oneCommand[1] <<
01407 "'... command is not w, r or d" << __E__;
01408 __SS_THROW__;
01409 }
01410
01412
01413 if(addressIsVariable)
01414 {
01415 if(argInHasBeenInitializedSet.find(oneCommand[2]) ==
01416 argInHasBeenInitializedSet.end())
01417 {
01418 argInHasBeenInitializedSet.emplace(oneCommand[2]);
01419
01420 if(!forFeMacro)
01421 {
01422
01423 out << tabOffset << "\t" <<
01424 "macroArgs[\"" <<
01425 oneCommand[2] << "\"] = theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode(" <<
01426 "\n" << tabOffset << "\t\t\"" <<
01427 oneCommand[2] << "\").getValue<uint64_t>();";
01428 }
01429 else
01430 {
01431 if(inArgNames) inArgNames->emplace(oneCommand[2]);
01432
01433
01434 out << tabOffset << "\t" <<
01435 "macroArgs[\"" <<
01436 oneCommand[2] << "\"] = __GET_ARG_IN__(\"" <<
01437 oneCommand[2] << "\", uint64_t);";
01438 }
01439 }
01440 out << "\t//get macro address argument";
01441 out << "\n" << tabOffset << "\tmemcpy(address,¯oArgs[\"" <<
01442 oneCommand[2] << "\"],8); //copy macro address argument to buffer";
01443
01444 }
01445 else
01446 {
01447 out << tabOffset << "\t" <<
01448 "macroAddress = 0x" << oneCommand[2] << "; memcpy(address,¯oAddress,8);" <<
01449 "\t//copy macro address to buffer";
01450 }
01451
01453
01454 if (oneCommand[1] == "w")
01455 {
01456 if(dataIsVariable)
01457 {
01458 if(argInHasBeenInitializedSet.find(oneCommand[3]) ==
01459 argInHasBeenInitializedSet.end())
01460 {
01461 argInHasBeenInitializedSet.emplace(oneCommand[3]);
01462
01463 if(forFeMacro)
01464 {
01465
01466 if(inArgNames) inArgNames->emplace(oneCommand[3]);
01467
01468
01469 out << "\n" << tabOffset << "\t" <<
01470 "macroArgs[\"" <<
01471 oneCommand[3] << "\"] = __GET_ARG_IN__(\"" <<
01472 oneCommand[3] << "\", uint64_t); //initialize from input arguments";
01473
01474
01475 }
01476 else
01477 {
01478
01479 out << "\n" << tabOffset << "\t" <<
01480 "macroArgs[\"" <<
01481 oneCommand[3] << "\"] = theXDAQContextConfigTree_.getNode(theConfigurationPath_).getNode(" <<
01482 "\n" << tabOffset << "\t\t\"" <<
01483 oneCommand[3] << "\").getValue<uint64_t>(); //initialize from configuration tree";
01484 }
01485 }
01486 out << "\t//get macro data argument";
01487 out << "\n" << tabOffset << "\tmemcpy(data,¯oArgs[\"" <<
01488 oneCommand[3] << "\"],8); //copy macro data argument to buffer";
01489 }
01490 else
01491 {
01492 out << "\n" << tabOffset << "\t" <<
01493 "macroData = 0x" << oneCommand[3] << "; memcpy(data,¯oData,8);" <<
01494 "\t//copy macro data to buffer";
01495 }
01496 out << "\n" << tabOffset << "\t" <<
01497 "universalWrite(address,data);";
01498 }
01499 else
01500 {
01501 out << "\n" << tabOffset << "\t" <<
01502 "universalRead(address,data);";
01503
01504
01505 std::string outputArgName;
01506
01507 if(dataIsVariable)
01508 outputArgName = oneCommand[3];
01509 else
01510 {
01511 char str[20];
01512 sprintf(str,"outArg%d",i);
01513 outputArgName = str;
01514 }
01515 __SUP_COUTV__(outputArgName);
01516
01517 out << tabOffset << "\t" <<
01518 "memcpy(¯oArgs[\"" <<
01519 outputArgName << "\"],data,8); //copy buffer to argument map";
01520
01521
01522 if(forFeMacro)
01523 out << "\n" << tabOffset << "\t" <<
01524 "__SET_ARG_OUT__(\"" <<
01525 outputArgName << "\",macroArgs[\"" <<
01526 outputArgName << "\"]); //update output argument result";
01527
01528 if(outArgNames) outArgNames->emplace(outputArgName);
01529 argInHasBeenInitializedSet.emplace(outputArgName);
01530 }
01531 }
01532
01533 out << "\n\n" << tabOffset << "\tdelete[] address; //free the memory";
01534 out << "\n" << tabOffset << "\tdelete[] data; //free the memory";
01535 out << "\n" << tabOffset << "}";
01536
01537 __SUP_COUT__ << "Done with code generation." << __E__;
01538 }
01539
01540
01541
01542
01543 bool MacroMakerSupervisor::isArgumentVariable(const std::string &argumentString)
01544 {
01545 for(unsigned int i=0; i<argumentString.length(); ++i)
01546 {
01547
01548 if(!((argumentString[i] >= '0' && argumentString[i] <= '9') ||
01549 (argumentString[i] >= 'a' && argumentString[i] <= 'f')||
01550 (argumentString[i] >= 'A' && argumentString[i] <= 'F')))
01551 return true;
01552 }
01553 return false;
01554 }
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565 std::string MacroMakerSupervisor::generateHexArray(const std::string &sourceHexString,
01566 int &numOfBytes)
01567 {
01568 std::stringstream retSs;
01569
01570 std::string srcHexStr = sourceHexString;
01571 __SUP_COUT__<< "Translating: \n";
01572 __SUP_COUT__ << srcHexStr << __E__;
01573
01574 if(srcHexStr.size()%2)
01575 srcHexStr = "0" + srcHexStr;
01576
01577 numOfBytes = srcHexStr.size()/2;
01578 retSs << "[" << numOfBytes << "] = {";
01579
01580 for(int i=0; i<numOfBytes*2; i+=2)
01581 {
01582
01583 if(!((srcHexStr[i] >= '0' && srcHexStr[i] <= '9') ||
01584 (srcHexStr[i] >= 'a' && srcHexStr[i] <= 'f')||
01585 (srcHexStr[i] >= 'A' && srcHexStr[i] <= 'F')) ||
01586 !((srcHexStr[i+1] >= '0' && srcHexStr[i+1] <= '9') ||
01587 (srcHexStr[i+1] >= 'a' && srcHexStr[i+1] <= 'f')||
01588 (srcHexStr[i+1] >= 'A' && srcHexStr[i+1] <= 'F'))
01589 )
01590 {
01591 numOfBytes = -1;
01592 return srcHexStr;
01593 }
01594
01595 if(i != 0) retSs << ", ";
01596 retSs << "0x" <<
01597 srcHexStr[srcHexStr.size()-1-i-1] <<
01598 srcHexStr[srcHexStr.size()-1-i];
01599 }
01600 retSs << "};";
01601
01602 __SUP_COUT__ << retSs.str() << __E__;
01603
01604 return retSs.str();
01605 }
01606
01607
01608 void MacroMakerSupervisor::runFEMacro(HttpXmlDocument& xmldoc, cgicc::Cgicc& cgi)
01609 {
01610 __SUP_COUT__<< __E__;
01611
01612 unsigned int feSupervisorID = CgiDataUtilities::getDataAsInt(cgi, "feSupervisorID");
01613 std::string feUID = CgiDataUtilities::getData(cgi, "feUID");
01614 std::string macroName = CgiDataUtilities::getData(cgi, "macroName");
01615 std::string inputArgs = CgiDataUtilities::postData(cgi, "inputArgs");
01616 std::string outputArgs = CgiDataUtilities::postData(cgi, "outputArgs");
01617
01618 __SUP_COUTV__(feSupervisorID);
01619 __SUP_COUTV__(feUID);
01620 __SUP_COUTV__(macroName);
01621 __SUP_COUTV__(inputArgs);
01622 __SUP_COUTV__(outputArgs);
01623
01624
01625 SOAPParameters txParameters;
01626 txParameters.addParameter("Request", "RunInterfaceMacro");
01627 txParameters.addParameter("InterfaceID", feUID);
01628 txParameters.addParameter("feMacroName", macroName);
01629 txParameters.addParameter("inputArgs", inputArgs);
01630 txParameters.addParameter("outputArgs", outputArgs);
01631
01632 SOAPParameters rxParameters;
01633 rxParameters.addParameter("success");
01634 rxParameters.addParameter("outputArgs");
01635
01636
01637
01638
01639 auto supervisorDescriptorPairIt = allFESupervisorInfo_.find(feSupervisorID);
01640 if(supervisorDescriptorPairIt == allFESupervisorInfo_.end())
01641 {
01642 __SS__ << "Targeted Supervisor Descriptor was not found. Attempted target " <<
01643 "was UID=" << feUID << " at feSupervisorID=" << feSupervisorID << "." << __E__;
01644 __SUP_COUT_ERR__ << "\n" << ss.str();
01645 xmldoc.addTextElementToData("Error",ss.str());
01646 return;
01647 }
01648
01649
01650 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
01651 supervisorDescriptorPairIt->second.getDescriptor(),
01652 "MacroMakerSupervisorRequest",
01653 txParameters);
01654 SOAPUtilities::receive(retMsg, rxParameters);
01655
01656 __SUP_COUT__ << "Received it " << __E__;
01657
01658 bool success = rxParameters.getValue("success") == "1";
01659 outputArgs = rxParameters.getValue("outputArgs");
01660
01661 __SUP_COUT__ << "rx success = " << success << __E__;
01662 __SUP_COUT__ << "outputArgs = " << outputArgs << __E__;
01663
01664 if(!success)
01665 {
01666 __SS__ << "Attempted FE Macro Failed. Attempted target " <<
01667 "was UID=" << feUID << " at feSupervisorID=" << feSupervisorID << "." << __E__;
01668 ss << "\n\n The error was:\n\n" << outputArgs << __E__;
01669 __SUP_COUT_ERR__ << "\n" << ss.str();
01670 xmldoc.addTextElementToData("Error",ss.str());
01671 return;
01672 }
01673
01674
01675
01676
01677 {
01678 std::istringstream inputStream(outputArgs);
01679 std::string splitVal, argName, argValue;
01680 while (getline(inputStream, splitVal, ';'))
01681 {
01682 std::istringstream pairInputStream(splitVal);
01683 getline(pairInputStream, argName, ',');
01684 getline(pairInputStream, argValue, ',');
01685 xmldoc.addTextElementToData("outputArgs_name",argName);
01686 xmldoc.addTextElementToData("outputArgs_value",argValue);
01687 __SUP_COUT__ << argName << ": " << argValue << __E__;
01688 }
01689 }
01690
01691 }
01692
01693
01694 void MacroMakerSupervisor::getFEMacroList(HttpXmlDocument& xmldoc, const std::string &username)
01695 {
01696 __SUP_COUT__<< "Getting FE Macro list" << __E__;
01697
01698 SOAPParameters txParameters;
01699 txParameters.addParameter("Request", "GetInterfaceMacros");
01700
01701 SOAPParameters rxParameters;
01702 rxParameters.addParameter("FEMacros");
01703
01704 std::string oneInterface;
01705 std::string rxFEMacros;
01706
01707
01708
01709
01710 for(auto &appInfo:allFESupervisorInfo_)
01711 {
01712 __SUP_COUT__ << "FESupervisor LID = " << appInfo.second.getId() <<
01713 " name = " << appInfo.second.getName() << __E__;
01714
01715 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
01716 appInfo.second.getDescriptor(),
01717 "MacroMakerSupervisorRequest",
01718 txParameters);
01719 SOAPUtilities::receive(retMsg, rxParameters);
01720
01721 rxFEMacros = rxParameters.getValue("FEMacros");
01722
01723 __SUP_COUT__ << "FE Macros received: \n" << rxFEMacros << __E__;
01724
01725 std::istringstream allInterfaces(rxFEMacros);
01726 while (std::getline(allInterfaces, oneInterface))
01727 {
01728
01729
01730 xmldoc.addTextElementToData("FEMacros",oneInterface);
01731
01732 }
01733 }
01734
01735
01736 loadMacros(xmldoc, username);
01737
01738 return;
01739 }
01740
01741
01742
01743
01744