00001
00002
00003
00004
00006 #include "JobControl/JobCPathModule.h"
00007 #include <cstring>
00008 #include "MessageService/MsgService.h"
00009 #include "JobControl/JobCPath.h"
00010 #include "JobControl/JobCommand.h"
00011 #include "JobControl/JobCPathRegistry.h"
00012 #include "JobControl/JobCModuleRegistry.h"
00013
00014 #include <cassert>
00015
00016 CVSID("$Id: JobCPathModule.cxx,v 1.28 2006/04/07 18:29:53 boehm Exp $");
00017 JOBMODULE(JobCPathModule,
00018 "Path",
00019 "Job control module for creating and managing job paths");
00020
00021 ClassImp(JobCPathModule)
00022
00023
00024
00025 static void sorry(const char* method)
00026 {
00027 MSG("JobC",Msg::kWarning) <<
00028 "Sorry, method " << method << " not implemented\n";
00029 }
00030
00031
00032
00033 JobCPathModule::JobCPathModule() :
00034 fMom(0),
00035 fInput(0),
00036 fPathRegistry(0),
00037 fDummyPath(0)
00038 { }
00039
00040
00041
00042 JobCPathModule::JobCPathModule(MomNavigator* mom,
00043 JobCInputModule* input) :
00044 fMom(mom),
00045 fInput(input),
00046 fPathRegistry(0),
00047 fDummyPath(0)
00048 { }
00049
00050
00051
00052 void JobCPathModule::SetPathRegistry(JobCPathRegistry* pr)
00053 {
00054 assert(pr);
00055 fPathRegistry = pr;
00056 }
00057
00058
00059
00060 JobCPathModule::~JobCPathModule()
00061 {
00062
00063
00064
00065
00066 if (fDummyPath) { delete fDummyPath; fDummyPath = 0; }
00067 }
00068
00069
00070
00071 void JobCPathModule::Add(const char* pathName, const char* nodes, int n)
00072 {
00073
00074
00075
00076
00077
00078
00079 JobCPath* p = fPathRegistry->LookUpPath(pathName);
00080 if (p) {
00081 int inode = 0;
00082 vector<string> nodelist;
00083 JobCommand::StringTok(nodelist, nodes, " ");
00084 vector<string>::iterator itr(nodelist.begin());
00085 vector<string>::iterator itrEnd(nodelist.end());
00086 for (; itr!=itrEnd; ++itr) {
00087 std::string module;
00088 std::string method;
00089 JobCommand::SplitLine((*itr).c_str(), ':', module, method);
00090 if (n>=0) {
00091 p->AddAt(module.c_str(),method.c_str(),n+inode);
00092 }
00093 else {
00094 p->PushBack(module.c_str(), method.c_str());
00095 }
00096 ++inode;
00097 }
00098 MSG("JobC", Msg::kDebug) << "\n" << (*p) << endl;
00099 }
00100 else {
00101 MSG("JobC",Msg::kWarning) << "Can not find path '" << pathName << "'\n";
00102 return;
00103 }
00104 }
00105
00106
00107
00108 JobCPath& JobCPathModule::Create(const char* pathName,
00109 const char* nodeList)
00110 {
00111
00112
00113
00114
00115
00116 JobCPath *path;
00117
00118
00119
00120 path = fPathRegistry->MakePath(pathName,fMom,fInput);
00121 if (path == 0) {
00122 MSG("JobC",Msg::kWarning) <<
00123 "Failed to make path '" << pathName << "'. May already exist!\n";
00124 static JobCPath dummy;
00125 return dummy;
00126 }
00127
00128
00129 vector<string> nodes;
00130 JobCommand::StringTok(nodes, nodeList, " ");
00131 vector<string>::iterator itr(nodes.begin());
00132 vector<string>::iterator itrEnd(nodes.end());
00133 for (; itr!=itrEnd; ++itr) {
00134 int len = strlen((*itr).c_str())+1;
00135 if (len>4) {
00136
00137 std::string module;
00138 std::string method;
00139 JobCommand::SplitLine((*itr).c_str(), ':', module, method);
00140 path->PushBack(module.c_str(), method.c_str());
00141 }
00142 else {
00143
00144 MSG("JobC",Msg::kWarning) <<
00145 "'" << (*itr) << "' is not a valid module::method pair.\n";
00146 MSG("JobC",Msg::kWarning) <<
00147 "Attempt to create unnamed module::method pair ignored.\n";
00148 }
00149 }
00150 #ifdef SITE_HAS_SIGC
00151 this->SigNewPath(path);
00152 #endif
00153 MSG("JobC", Msg::kDebug) << "\n" << (*path) << endl;
00154 return *path;
00155 }
00156
00157
00158
00159 void JobCPathModule::Delete(const char* path)
00160 {
00161
00162
00163
00164 fPathRegistry->DeletePath(path);
00165 }
00166
00167
00168
00169 void JobCPathModule::HandleCommand(JobCommand *cmd)
00170 {
00171
00172
00173
00174
00175
00176 string c = cmd->PopCmd();
00177 if (c=="Create") {
00178 string path = cmd->PopOpt();
00179 string nodes;
00180 while (cmd->HaveOpt()) {
00181 nodes += cmd->PopOpt();
00182 nodes += " ";
00183 }
00184 this->Create(path.c_str(), nodes.c_str());
00185 return;
00186 }
00187 if (c=="Delete") {
00188 const char* path = cmd->PopOpt();
00189 this->Delete(path);
00190 return;
00191 }
00192 if (c=="Add") {
00193 const char* path = cmd->PopOpt();
00194 string nodes;
00195 while (cmd->HaveOpt()) {
00196 nodes += cmd->PopOpt();
00197 nodes += " ";
00198 }
00199 this->Add(path, nodes.c_str());
00200 return;
00201 }
00202 if (c=="Remove") {
00203 this->Remove();
00204 return;
00205 }
00206 if (c=="Attach") {
00207 const char* upStreamPath = cmd->PopOpt();
00208 const char* dnStreamPath = cmd->PopOpt();
00209 this->Attach(upStreamPath, dnStreamPath);
00210 return;
00211 }
00212 if (c=="Detach") {
00213 const char* path1 = cmd->PopOpt();
00214 const char* path2 = cmd->PopOpt();
00215 this->Detach(path1, path2);
00216 return;
00217 }
00218
00219 MSG("JobC",Msg::kWarning) <<
00220 "Module " << this->GetName() <<
00221 " does not implement command " << c << "." << endl;
00222 }
00223
00224
00225
00226 void JobCPathModule::Help()
00227 {
00228
00229
00230
00231 static const char* help =
00232 "Help for 'Path' module:\n"
00233 "\n"
00234 " Path is a module for creating and holding the job paths and\n"
00235 " job modules used by your job. Possible commands are:\n"
00236 "\n"
00237 " /Path/Add <path> <module>::<method>\n"
00238 " /Path/Add <path> <module>::<method> <position>\n"
00239 "\n"
00240 " Add module's '<module>' '<method>' to the path 'path' at\n"
00241 " the <position> (1,2,3...). <position> is optional.\n"
00242 "\n"
00243 " /Path/Create <path>\n"
00244 " /Path/Create <path> <mod1>::<meth1> <mod2>::<meth2> ...\n"
00245 "\n"
00246 " Create a path named 'path' and add nodes specified by the module \n"
00247 " and method pairs <mod>::<meth> to it.\n"
00248 "\n"
00249 " /Path/Delete <path>\n"
00250 "\n"
00251 " Delete the path named '<path>'\n"
00252 "\n"
00253 " /Path/Remove <module>\n"
00254 " /Path/Remove <module>::<method>\n"
00255 "\n"
00256 " Remove the node <module>::<method> from a path\n"
00257 " If <method> is not specified all nodes using <module> are removed.\n"
00258 "\n"
00259 " /Path/Attach <path1> <path2>\n"
00260 " /Path/Detach <path1> <path2>\n"
00261 "\n"
00262 " Attach/Detach <path2> to/from <path1>\n";
00263 MSG("JobC", Msg::kInfo) << help << endl;
00264 }
00265
00266
00267
00268 void JobCPathModule::Remove()
00269 {
00270 sorry("JobCPathModule::Remove");
00271 }
00272
00273
00274
00275 void JobCPathModule::Attach(const char* n1, const char* n2)
00276 {
00277
00278
00279
00280 if (n1==0 || n2==0) {
00281 MSG("JobC",Msg::kError) <<
00282 "Attach requires two path names as arguments.\n" <<
00283 "Example: '" <<
00284 this->GetName() << "/Attach path1 path2' will attach path2 to path1\n";
00285 return;
00286 }
00287 JobCPath *p1 = fPathRegistry->LookUpPath(n1);
00288 if (p1==0) {
00289 MSG("JobC",Msg::kError) << "Path '" << n1 << "' not found.\n";
00290 return;
00291 }
00292 JobCPath *p2 = fPathRegistry->LookUpPath(n2);
00293 if (p2==0) {
00294 MSG("JobC",Msg::kError) << "Path '" << n2 << "' not found.\n";
00295 return;
00296 }
00297
00298 p1->Attach(p2);
00299 }
00300
00301
00302
00303 void JobCPathModule::Detach(const char* pathA, const char* pathB)
00304 {
00305 MSG("JobC",Msg::kWarning) <<
00306 "Detach(" << pathA << "," << pathB <<") \n";
00307 sorry("JobCPathModule::Detach");
00308 }
00309
00310
00311
00312 void JobCPathModule::Report()
00313 {
00314
00315
00316
00317 JobCPathRegistry::PathIterator itr(fPathRegistry->GetPathBegin());
00318 JobCPathRegistry::PathIterator itrEnd(fPathRegistry->GetPathEnd());
00319 bool ifirst = true;
00320 if (itr==itrEnd) {
00321 MSG("JobCReport",Msg::kInfo) <<
00322 "...................................." <<
00323 "....................................\n" <<
00324 "<no active paths>\n" <<
00325 "...................................." <<
00326 "....................................\n";
00327 return;
00328 }
00329 for (; itr!=itrEnd; ++itr) {
00330 if (ifirst) {
00331 MSG("JobCReport",Msg::kInfo) <<
00332 "...................................." <<
00333 "....................................\n";
00334 ifirst = false;
00335 }
00336 MSG("JobCReport",Msg::kInfo) <<
00337 (*(*itr)) <<
00338 "...................................." <<
00339 "....................................\n";
00340 }
00341 }
00342
00343
00344
00345 void JobCPathModule::Reset() { fPathRegistry->Reset(); }
00346
00347
00348
00349 JobCPath& JobCPathModule::operator()(const char* path)
00350 {
00351
00352
00353
00354 JobCPath* p = fPathRegistry->LookUpPath(path);
00355 if (p!=0) return (*p);
00356
00357 MSG("JobC",Msg::kWarning) << "Failed to find path '" << path << "'.\n";
00358 if (fDummyPath == 0) fDummyPath = new JobCPath;
00359 return (*fDummyPath);
00360 }
00361