Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

JobCPathModule.cxx

Go to the documentation of this file.
00001 
00002 // $Id: JobCPathModule.cxx,v 1.28 2006/04/07 18:29:53 boehm Exp $
00003 //
00004 // messier@huhepl.harvard.edu
00006 #include "JobControl/JobCPathModule.h"
00007 #include <cstring> // strcmp
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" // JOBMODULE macro
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 //Purpose: Delete the Path modules -- delete the paths owned by the
00064 //         module
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 // Purpose: Add a module::method pair to a path. The expected order of
00075 // options is: <path_name> <module>::<method> <module>::<method> ...
00076 //
00077 // Inputs: cmd - the job command
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 // Purpose: Given a command line create a job path
00113 //
00114 // Inputs: cmd - The job command
00115 //======================================================================
00116   JobCPath *path;
00117 
00118   // Create the path and add it to the list ** Remember this module
00119   // owns the paths and has the responsibility to delete them! **
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   // Loop over remaining options and add nodes to the path
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) { // Need at least 4 char's to create a node name: 'a:b\0'
00136       // Valid node name
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       // Invalid node name
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 // Delete a path from the registry
00163 //======================================================================
00164   fPathRegistry->DeletePath(path);
00165 }
00166 
00167 //......................................................................
00168 
00169 void JobCPathModule::HandleCommand(JobCommand *cmd) 
00170 {
00171 //======================================================================
00172 // Purpose: Switchyard for commands
00173 // 
00174 // Input: cmd - the job command
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   // Fall through to here if nothing has handled the command
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 // Purpose: Print help for this job module
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 // Purpose: Handle the "Attach" command which links one path to another
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   // Stick p2 onto p1
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 // Print report for all active paths
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)) << // Whoa, pointer to pointer...
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 // Return a path by name
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 

Generated on Mon Feb 15 11:06:49 2010 for loon by  doxygen 1.3.9.1