00001
00002
00003
00004
00005
00006
00008 #include "JobControl/JobController.h"
00009 #include <fstream>
00010 #include "MessageService/MsgService.h"
00011 #include "JobControl/JobCommand.h"
00012 #include "JobControl/JobCInterpreter.h"
00013 #include "JobControl/JobCEnv.h"
00014 #include "JobControl/JobCPath.h"
00015 #include "JobControl/JobCPathHandler.h"
00016 #include "JobControl/JobCPathRegistry.h"
00017 #include "JobControl/JobCNode.h"
00018 #include "JobControl/JobCModule.h"
00019 #include "JobControl/JobCModuleProxy.h"
00020 #include "JobControl/JobCModuleRegistry.h"
00021 #include "JobControl/JobCPathModule.h"
00022
00023 #include <cassert>
00024
00025 CVSID("$Id: JobController.cxx,v 1.29 2003/08/26 23:04:23 messier Exp $");
00026
00027
00028 JobController* JobController::fMotherController = 0;
00029
00030
00031
00032 JobController::JobController() :
00033 fPathRegistry(new JobCPathRegistry()),
00034 fInterp(new JobCInterpreter())
00035 {
00036
00037
00038
00039
00040
00041 this->Init();
00042 }
00043
00044
00045
00046 JobController::JobController(int argc, char** argv) :
00047 fPathRegistry(new JobCPathRegistry()),
00048 fInterp(new JobCInterpreter())
00049 {
00050
00051
00052
00053
00054
00055
00056 JobCEnv::Instance(argc, argv);
00057
00058
00059 this->Init();
00060 }
00061
00062
00063
00064 JobController::~JobController()
00065 {
00066 MSG("JobC",Msg::kVerbose) <<
00067 "Shutting down JobController @ " << this << "\n";
00068
00069 if (fInterp) {delete fInterp; fInterp = 0; }
00070 if (fPathRegistry) {delete fPathRegistry; fPathRegistry = 0; }
00071
00072 if (this == fMotherController) fMotherController = 0;
00073 }
00074
00075
00076
00077 JobCEnv* JobController::GetJobEnv() const
00078 {
00079 JobCEnv& env = JobCEnv::Instance();
00080 return &env;
00081 }
00082
00083
00084
00085 MomNavigator* JobController::GetMom()
00086 {
00087 return &fMom;
00088 }
00089
00090
00091
00092 JobCPathRegistry* JobController::GetPathRegistry() const {
00093 return fPathRegistry;
00094 }
00095
00096
00097
00098 JobController* JobController::GetMotherController()
00099 {
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 if (fMotherController) {
00111 return fMotherController;
00112 }
00113 else {
00114
00115
00116 static JobController motherController;
00117
00118
00119
00120 assert(fMotherController);
00121 return fMotherController;
00122 }
00123 return 0;
00124 }
00125
00126
00127
00128 void JobController::operator()(const char *c) { (*this) << c << "\n"; }
00129
00130
00131
00132 JobController& JobController::operator<<(const char* cmd)
00133 {
00134
00135
00136
00137
00138 (*fInterp) << cmd;
00139
00140
00141 if (JobCEnv::Instance().IsBatch()==false) this->ProcessCommands();
00142
00143 return *this;
00144 }
00145
00146
00147
00148 bool JobController::ControllerCommand(JobCommand *cmd)
00149 {
00150
00151
00152
00153 string c1 = cmd->PopCmd();
00154 if (c1 == "echo" || c1 == "Echo" || c1 == "ECHO") {
00155
00156 if (cmd->HaveOpt()) {
00157 string c2 = cmd->PopOpt();
00158 if (c2 == "on" || c2 == "On" || c2 == "ON") {
00159 fInterp->EchoOn();
00160 return true;
00161 }
00162 if (c2 == "off" || c2 == "Off" || c2 == "OFF") {
00163 fInterp->EchoOff();
00164 return true;
00165 }
00166 }
00167 else {
00168
00169 fInterp->EchoOn();
00170 return true;
00171 }
00172 }
00173 if (c1 == "help" || c1 == "Help" || c1 == "HELP") {
00174
00175 this->Help(cmd);
00176 return true;
00177 }
00178 if (c1 == "Exec" || c1 == "exec" || c1 == "EXEC") {
00179 if (cmd->HaveOpt()) {
00180 string macrofile = cmd->PopOpt();
00181 this->ReadMacroFile(macrofile.c_str());
00182 return true;
00183 }
00184 else {
00185 MSG("JobC",Msg::kWarning) << "Need JobControl macro file.\n";
00186 return false;
00187 }
00188 }
00189
00190
00191 cmd->PushCmd();
00192 return false;
00193 }
00194
00195
00196
00197 void JobController::HandleCommand(JobCommand *cmd)
00198 {
00199
00200
00201
00202
00203
00204
00205
00206 const char *c1;
00207 JobCPath *path =0;
00208 JobCModule *module=0;
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 if (this->ControllerCommand(cmd)) return;
00225
00226
00227 c1 = cmd->PopCmd();
00228 path = fPathRegistry->LookUpPath(c1);
00229 if (path) {
00230
00231 const char *c2;
00232 c2 = cmd->PopCmd();
00233
00234 if (c2) {
00235 module = path->GetModule(c2);
00236 if (module == 0) {
00237
00238 cmd->PushCmd();
00239 JobCPathHandler ph(path);
00240 ph.HandleCommand(cmd);
00241 return;
00242 }
00243 }
00244 }
00245 else {
00246
00247 module = fPathRegistry->LookUpModule(c1);
00248 if ( module == 0 ) {
00249
00250 MSG("JobC",Msg::kWarning)
00251 << "Failed to find '" << c1 << "'.\n";
00252 return;
00253 }
00254 }
00255
00256
00257
00258 module->HandleCommand(cmd);
00259 }
00260
00261
00262
00263 void JobController::Help(JobCommand *cmd)
00264 {
00265 if (cmd->HaveOpt()) {
00266 while (cmd->HaveOpt()) {
00267
00268 const char *opt = cmd->PopOpt();
00269 JobCModuleProxy* mp = JobCModuleRegistry::Instance().LookUp(opt);
00270 if (mp) {
00271 mp->Help();
00272 }
00273 else {
00274 MSG("JobC", Msg::kWarning) << "Can not find module " << opt << endl;
00275 }
00276 }
00277 }
00278 else {
00279 MSG("JobC",Msg::kInfo) <<
00280 "===================================="
00281 "====================================\n" <<
00282 " JOBCONTROL HELP\n" <<
00283 "\n" <<
00284 " In general job control commands are of the format:\n" <<
00285 " /[path]/[module]/[command] [option1] [option2] ...\n" <<
00286 "\n" <<
00287 " where [path] is a name of a job path\n" <<
00288 " [module] is a name of a job module\n" <<
00289 " [command] is the name of a command to send to the module\n" <<
00290 " [option] is a possible option for the command\n" <<
00291 "\n" <<
00292 " Commands are in general case sensitive.\n" <<
00293 "\n" <<
00294 " For help with a specific job module try:\n" <<
00295 " Help [module1] [module2] ...\n" <<
00296 "\n" <<
00297 " The following is a list of " <<
00298 JobCModuleRegistry::Instance() <<
00299 "===================================="
00300 "====================================" << endl;
00301 }
00302 }
00303
00304
00305
00306 void JobController::Init(void)
00307 {
00308
00309
00310
00311
00312 if (JobCEnv::Instance().GetModuleHelpList()) {
00313 (*this) << "Help " << JobCEnv::Instance().GetModuleHelpList() << "\n";
00314 this->Run();
00315 exit(1);
00316 }
00317
00318
00319 if (fMotherController == 0) fMotherController = this;
00320
00321
00322 this->BuildSystemPath();
00323
00324
00325 const char *macrofile;
00326 for (unsigned int i=0;
00327 (macrofile=JobCEnv::Instance().GetMacroFile(i))!=0;
00328 ++i) {
00329 this->ReadMacroFile(macrofile);
00330 }
00331 }
00332
00333
00334
00335 void JobController::BuildSystemPath()
00336 {
00337
00338
00339
00340
00341
00342 JobCPath* syspath = fPathRegistry->MakePath(".jobcontroller",&fMom,0);
00343 assert(syspath);
00344
00345
00346 JobCNode* dn = syspath->PushBack("Display","Void");
00347 JobCNode* mn = syspath->PushBack("Msg", "Void");
00348 JobCNode* pn = syspath->PushBack("Path", "Void");
00349 JobCNode* rn = syspath->PushBack("Root", "Void");
00350
00351
00352 JobCPathModule* pm = static_cast<JobCPathModule*>(pn->GetModule());
00353 assert(pm);
00354 pm->SetPathRegistry(fPathRegistry);
00355 pm->SetMom(&fMom);
00356
00357 dn->GetModule()->BeginJob();
00358 mn->GetModule()->BeginJob();
00359 pn->GetModule()->BeginJob();
00360 rn->GetModule()->BeginJob();
00361 }
00362
00363
00364
00365 void JobController::ProcessCommands()
00366 {
00367
00368
00369
00370 while (JobCommand* jc = fInterp->PopJobCommand()) {
00371 this->HandleCommand(jc);
00372 }
00373 }
00374
00375
00376
00377 void JobController::ReadMacroFile(const char *filename)
00378 {
00379
00380
00381
00382 ifstream ifs(filename);
00383
00384 if (ifs.bad()) {
00385 MSG("JobC",Msg::kWarning) <<
00386 "Macro file '" << filename << "' does not exist.\n";
00387 return;
00388 }
00389 else {
00390 const unsigned int bufs = 2048;
00391 char c[bufs];
00392 string s;
00393 while (ifs.good()) {
00394 ifs.getline(c,bufs,'\n');
00395 s = c;
00396 s += '\n';
00397 (*this) << s.c_str();
00398 }
00399 }
00400 }
00401
00402
00403
00404 int JobController::Run()
00405 {
00406
00407
00408
00409 this->ProcessCommands();
00410 JobCEnv::Instance().RunRootApp();
00411 return 1;
00412 }
00413