00001
00002
00003
00004
00005
00006
00008
00009
00010 #include "EventFilter/Utilities/interface/WebGUI.h"
00011
00012 #include "xcept/Exception.h"
00013 #include "xcept/tools.h"
00014
00015 #include "cgicc/CgiDefs.h"
00016 #include "cgicc/Cgicc.h"
00017 #include "cgicc/HTMLClasses.h"
00018
00019 #include <sstream>
00020
00021
00022 using namespace std;
00023 using namespace evf;
00024 using namespace cgicc;
00025
00026
00028
00030
00031
00032 WebGUI::WebGUI(xdaq::Application* app,StateMachine* fsm)
00033 : app_(app)
00034 , fsm_(fsm)
00035 , log_(app->getApplicationContext()->getLogger())
00036 , appInfoSpace_(0)
00037 , monInfoSpace_(0)
00038 , itemGroupListener_(0)
00039 , parametersExported_(false)
00040 , countersAddedToParams_(false)
00041 , largeAppIcon_("/evf/images/rbicon.jpg")
00042 , smallAppIcon_("/evf/images/rbicon.jpg")
00043 , smallDbgIcon_("/evf/images/bugicon.jpg")
00044 , smallCtmIcon_("/evf/images/spoticon.jpg")
00045 , hyperDAQIcon_("/hyperdaq/images/HyperDAQ.jpg")
00046 {
00047
00048 string appClass=app_->getApplicationDescriptor()->getClassName();
00049 unsigned int instance=app_->getApplicationDescriptor()->getInstance();
00050 stringstream oss;
00051 oss<<appClass<<instance;
00052
00053 sourceId_=oss.str();
00054 urn_ ="/"+app_->getApplicationDescriptor()->getURN();
00055
00056 std::stringstream oss2;
00057 oss2<<"urn:xdaq-monitorable-"<<appClass;
00058 string monInfoSpaceName=oss2.str();
00059 toolbox::net::URN urn = app_->createQualifiedInfoSpace(monInfoSpaceName);
00060
00061 appInfoSpace_=app_->getApplicationInfoSpace();
00062 monInfoSpace_=xdata::getInfoSpaceFactory()->get(urn.toString());
00063 app_->getApplicationDescriptor()->setAttribute("icon",largeAppIcon_);
00064
00065
00066 xgi::bind(this,&WebGUI::defaultWebPage,"defaultWebPage");
00067 xgi::bind(this,&WebGUI::debugWebPage, "debugWebPage");
00068 xgi::bind(this,&WebGUI::css, "styles.css");
00069
00070
00071 itemGroupListener_ = dynamic_cast<xdata::ActionListener*>(app_);
00072 if (0!=itemGroupListener_) {
00073 appInfoSpace()->addGroupRetrieveListener(itemGroupListener_);
00074 monInfoSpace()->addGroupRetrieveListener(itemGroupListener_);
00075 }
00076 }
00077
00078
00079
00080 WebGUI::~WebGUI()
00081 {
00082
00083 }
00084
00085
00087
00089
00090
00091 void WebGUI::defaultWebPage(Input_t *in,Output_t *out) throw (WebGUI::XgiException_t)
00092 {
00093 updateParams();
00094
00095 *out<<"<html>"<<endl;
00096 htmlHead(in,out,sourceId_);
00097 *out<<body()<<endl;
00098 htmlHeadline(in,out);
00099 *out<<"<table cellpadding=\"25\"><tr valign=\"top\"><td>"<<endl;
00100 htmlTable(in,out,"Standard Parameters",standardParams_);
00101 *out<<"</td><td>"<<endl;
00102 htmlTable(in,out,"Monitored Parameters",monitorParams_);
00103 *out<<"</td></tr></table>"<<endl;
00104 *out<<body()<<endl<<"</html>"<<endl;
00105 return;
00106 }
00107
00108
00109
00110 void WebGUI::debugWebPage(Input_t *in,Output_t *out) throw (WebGUI::XgiException_t)
00111 {
00112 updateParams();
00113
00114 *out<<"<html>"<<endl;
00115 htmlHead(in,out,sourceId_+" [DEBUG]");
00116 *out<<body()<<endl;
00117 htmlHeadline(in,out);
00118 *out<<"<table cellpadding=\"25\"><tr valign=\"top\"><td>"<<endl;
00119 htmlTable(in,out,"Debug Parameters",debugParams_);
00120 *out<<"</td></tr></table>"<<endl;
00121 *out<<body()<<endl<<"</html>"<<endl;
00122 return;
00123 }
00124
00125
00126
00127 void WebGUI::css(Input_t *in,Output_t *out) throw (WebGUI::XgiException_t)
00128 {
00129 css_.css(in,out);
00130 }
00131
00132
00133
00134 void WebGUI::addStandardParam(CString_t& name,Param_t* param)
00135 {
00136 if (parametersExported_) {
00137 LOG4CPLUS_ERROR(log_,"Failed to add standard parameter '"<<name<<"'.");
00138 return;
00139 }
00140 standardParams_.push_back(make_pair(name,param));
00141 }
00142
00143
00144
00145 void WebGUI::addMonitorParam(CString_t& name,Param_t* param)
00146 {
00147 if (parametersExported_) {
00148 LOG4CPLUS_ERROR(log_,"Failed to add monitor parameter '"<<name<<"'.");
00149 return;
00150 }
00151 monitorParams_.push_back(make_pair(name,param));
00152 }
00153
00154
00155
00156 void WebGUI::addDebugParam(CString_t& name,Param_t* param)
00157 {
00158 if (parametersExported_) {
00159 LOG4CPLUS_ERROR(log_,"Failed to add debug parameter '"<<name<<"'.");
00160 return;
00161 }
00162 debugParams_.push_back(make_pair(name,param));
00163 }
00164
00165
00166
00167 void WebGUI::addStandardCounter(CString_t& name,Counter_t* counter)
00168 {
00169 if (countersAddedToParams_) {
00170 LOG4CPLUS_ERROR(log_,"can't add standard counter '"<<name
00171 <<"' to WebGUI of "<<sourceId_);
00172 }
00173 standardCounters_.push_back(make_pair(name,counter));
00174 }
00175
00176
00177
00178 void WebGUI::addMonitorCounter(CString_t& name,Counter_t* counter)
00179 {
00180 if (countersAddedToParams_) {
00181 LOG4CPLUS_ERROR(log_,"can't add monitor counter '"<<name
00182 <<"' to WebGUI of "<<sourceId_);
00183 }
00184 monitorCounters_.push_back(make_pair(name,counter));
00185 }
00186
00187
00188
00189 void WebGUI::addDebugCounter(CString_t& name,Counter_t* counter)
00190 {
00191 if (countersAddedToParams_) {
00192 LOG4CPLUS_ERROR(log_,"can't add debug counter '"<<name
00193 <<"' to WebGUI of "<<sourceId_);
00194 }
00195 debugCounters_.push_back(make_pair(name,counter));
00196 }
00197
00198
00199
00200 void WebGUI::exportParameters()
00201 {
00202 if (parametersExported_) return;
00203
00204 if (!countersAddedToParams_) addCountersToParams();
00205
00206 addParamsToInfoSpace(standardParams_,appInfoSpace());
00207 addParamsToInfoSpace(monitorParams_, appInfoSpace());
00208 addParamsToInfoSpace(debugParams_, appInfoSpace());
00209
00210 addParamsToInfoSpace(monitorParams_,monInfoSpace());
00211
00212 parametersExported_=true;
00213 }
00214
00215
00216
00217 void WebGUI::resetCounters()
00218 {
00219
00220 for (unsigned int i=0;i<standardCounters_.size();i++) {
00221 Counter_t* counter=standardCounters_[i].second;
00222 *counter=0;
00223 }
00224
00225 for (unsigned int i=0;i<monitorCounters_.size();i++) {
00226 Counter_t* counter=monitorCounters_[i].second;
00227 *counter=0;
00228 }
00229
00230 for (unsigned int i=0;i<debugCounters_.size();i++) {
00231 Counter_t* counter=debugCounters_[i].second;
00232 *counter=0;
00233 }
00234 }
00235
00236
00237
00238 void WebGUI::addItemChangedListener(CString_t& name,xdata::ActionListener* l)
00239 {
00240 if (!parametersExported_) {
00241 LOG4CPLUS_ERROR(log_,"Can't add ItemChangedListener for parameter '"<<name
00242 <<"' before WebGUI::exportParameters() is called.");
00243 return;
00244 }
00245
00246 try {
00247 appInfoSpace()->addItemChangedListener(name,l);
00248 }
00249 catch (xcept::Exception) {
00250 LOG4CPLUS_ERROR(log_,"failed to add ItemChangedListener to "
00251 <<"application infospace for parameter '"<<name<<"'.");
00252 }
00253
00254 if (isMonitorParam(name)) {
00255 try {
00256 monInfoSpace()->addItemChangedListener(name,l);
00257 }
00258 catch (xcept::Exception) {
00259 LOG4CPLUS_ERROR(log_,"failed to add ItemChangedListener to "
00260 <<"monitor infospace for parameter '"<<name<<"'.");
00261 }
00262 }
00263
00264 }
00265
00266
00268
00270
00271
00272 void WebGUI::addParamsToInfoSpace(const ParamVec_t& params,
00273 xdata::InfoSpace* infoSpace)
00274 {
00275 for (unsigned int i=0;i<params.size();i++) {
00276 string name =params[i].first;
00277 Param_t* value=params[i].second;
00278 try {
00279 infoSpace->fireItemAvailable(name,value);
00280 }
00281 catch (xcept::Exception &e) {
00282 LOG4CPLUS_ERROR(log_,"Can't add parameter '"<<name<<"' to info space '"
00283 <<infoSpace->name()<<"': "
00284 <<xcept::stdformat_exception_history(e));
00285 }
00286 }
00287 }
00288
00289
00290
00291 void WebGUI::addCountersToParams()
00292 {
00293 if (countersAddedToParams_) return;
00294
00295
00296 for (unsigned int i=0;i<standardCounters_.size();i++) {
00297 standardParams_.push_back(make_pair(standardCounters_[i].first,
00298 standardCounters_[i].second));
00299 }
00300
00301 for (unsigned int i=0;i<monitorCounters_.size();i++) {
00302 monitorParams_.push_back(make_pair(monitorCounters_[i].first,
00303 monitorCounters_[i].second));
00304 }
00305
00306 for (unsigned int i=0;i<debugCounters_.size();i++) {
00307 debugParams_.push_back(make_pair(debugCounters_[i].first,
00308 debugCounters_[i].second));
00309 }
00310 countersAddedToParams_=true;
00311 }
00312
00313
00314
00315 bool WebGUI::isMonitorParam(CString_t& name)
00316 {
00317 ParamVec_t::const_iterator it;
00318 for (it=monitorParams_.begin();it!=monitorParams_.end();++it)
00319 if (it->first==name) return true;
00320 return false;
00321 }
00322
00323
00324
00325 void WebGUI::updateParams()
00326 {
00327 if (0!=itemGroupListener_) {
00328 std::list<std::string> emptyList;
00329 appInfoSpace()->fireItemGroupRetrieve(emptyList,itemGroupListener_);
00330 }
00331 }
00332
00333
00334
00335 void WebGUI::htmlTable(Input_t*in,Output_t*out,
00336 CString_t& title,const ParamVec_t& params)
00337 {
00338 *out<<table().set("frame","void").set("rules","rows")
00339 .set("class","modules").set("width","300")<<endl
00340 <<tr()<<th(title).set("colspan","2")<<tr()<<endl
00341 <<tr()
00342 <<th("Parameter").set("align","left")
00343 <<th("Value").set("align","right")
00344 <<tr()
00345 <<endl;
00346
00347 for (unsigned int i=0;i<params.size();i++) {
00348 string valueAsString;
00349 try {
00350 valueAsString = params[i].second->toString();
00351 }
00352 catch (xcept::Exception& e) {
00353 valueAsString = e.what();
00354 }
00355 *out<<tr()
00356 <<td(params[i].first).set("align","left")
00357 <<td(valueAsString).set("align","right")
00358 <<tr()<<endl;
00359 }
00360 *out<<table()<<endl;
00361 }
00362
00363
00364
00365 void WebGUI::htmlHead(Input_t *in,Output_t* out,CString_t& pageTitle)
00366 {
00367 *out<<head()<<endl<<cgicc::link().set("type","text/css")
00368 .set("rel","stylesheet")
00369 .set("href",urn_+"/styles.css")
00370 <<endl<<title(pageTitle.c_str())<<endl<<head()<<endl;
00371 }
00372
00373
00374
00375 void WebGUI::htmlHeadline(Input_t *in,Output_t *out)
00376 {
00377 string stateName=fsm_->stateName()->toString();
00378
00379 *out<<table().set("border","0").set("width","100%")<<endl
00380 <<tr()<<td().set("align","left")<<endl
00381 <<img().set("align","middle").set("src",largeAppIcon_)
00382 .set("alt","main") .set("width","64")
00383 .set("height","64") .set("border","")
00384 <<endl
00385 <<b()<<sourceId_<<" "<<stateName<<b()<<endl
00386 <<td()<<endl
00387 <<td().set("width","32")<<endl
00388 <<a().set("href","/urn:xdaq-application:lid=3")
00389 <<img().set("align","middle").set("src",hyperDAQIcon_)
00390 .set("alt","HyperDAQ").set("width","32")
00391 .set("height","32") .set("border","")
00392 <<a()
00393 <<td()<<endl
00394 <<td().set("width","32")<<td()
00395 <<td().set("width","32")
00396 <<a().set("href",urn_+"/defaultWebPage")
00397 <<img().set("align","middle").set("src",smallAppIcon_)
00398 .set("alt","Debug") .set("width","32")
00399 .set("height","32") .set("border","")
00400 <<a()
00401 <<td()<<endl
00402 <<td().set("width","32")<<td()
00403 <<td().set("width","32")
00404 <<a().set("href",urn_+"/debugWebPage")
00405 <<img().set("align","middle").set("src",smallDbgIcon_)
00406 .set("alt","Debug") .set("width","32")
00407 .set("height","32") .set("border","")
00408 <<a()
00409 <<td()<<endl
00410 <<td().set("width","32")<<td()
00411 <<td().set("width","32")
00412 <<a().set("href",urn_+"/customWebPage")
00413 <<img().set("align","middle").set("src",smallCtmIcon_)
00414 .set("alt","Debug") .set("width","32")
00415 .set("height","32") .set("border","")
00416 <<a()
00417 <<td()<<tr()<<table()<<endl;
00418 *out<<hr()<<endl;
00419 }