1 /*=========================================================================
4 Module: $RCSfile: bbtkFactory.cxx,v $
7 Date: $Date: 2008/01/22 15:02:00 $
8 Version: $Revision: 1.1 $
11 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
12 l'Image). All rights reserved. See doc/license.txt or
13 http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
15 This software is distributed WITHOUT ANY WARRANTY; without even
16 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 PURPOSE. See the above copyright notices for more information.
19 =========================================================================*/
22 *\brief Class bbtk::Factory : can load and unload dynamic libraries containing
23 * black boxes packages and create instances of the black boxes registered
24 * in the packages loaded.
26 #include "bbtkFactory.h"
27 #include "bbtkMessageManager.h"
28 #include "bbtkConnection.h"
29 #include "bbtkConfigurationFile.h"
31 #include <sys/stat.h> // for struct stat stFileInfo
34 #include <direct.h> // for getcwd
41 # define getcwd _getcwd
44 #if defined(_MSC_VER) || defined(__BORLANDC__)
55 typedef Package* (*PackageAccessor)();
56 typedef void (*PackageDeleteFunction)();
59 //===================================================================
63 bbtkDebugMessage("Core",7,"Factory::Factory()"<<std::endl);
65 //===================================================================
67 //===================================================================
71 bbtkDebugMessageInc("Core",7,"Factory::~Factory()"<<std::endl);
73 bbtkDebugDecTab("Core",7);
75 //===================================================================
78 //===================================================================
79 void Factory::CloseAllPackages()
81 bbtkDebugMessageInc("Core",7,"Factory::CloseAllPackages()"<<std::endl);
82 while (mPackageMap.begin() != mPackageMap.end())
84 PackageMapType::iterator i = mPackageMap.begin();
87 bbtkDebugDecTab("Core",7);
89 //===================================================================
91 //===================================================================
94 bbtkDebugMessageInc("Core",7,"Factory::Reset()"<<std::endl);
96 bbtkDebugDecTab("Core",7);
98 //===================================================================
100 // --> usefull in many places (at least : ConfigurationFile, Factory, Interpreter)
101 // should be factorized ( "bbtk::Util class ?)
103 bool Factory::FileExists(std::string strFilename)
104 bool Factory::IsAtRoot(std::string cwd)
105 std::string Factory::ExtractPackageName(const std::string &name)
106 std::string Factory::ExpandLibName(const std::string &name, bool verbose)
107 std::string Factory::MakeLibnameFromPath(std::string path, std::string pkgname)
108 bool Factory::CheckIfLibraryContainsPackage(std::string libname,std::string pkgname, bool verbose)
111 // See : http://www.techbytes.ca/techbyte103.html for more O.S.
112 bool Factory::FileExists(std::string strFilename) {
113 struct stat stFileInfo;
117 // Attempt to get the file attributes
118 intStat = stat(strFilename.c_str(),&stFileInfo);
120 // We were able to get the file attributes
121 // so the file obviously exists.
124 // We were not able to get the file attributes.
125 // This may mean that we don't have permission to
126 // access the folder which contains this file. If you
127 // need to do that level of checking, lookup the
128 // return values of stat which will give you
129 // more details on why stat failed.
136 // ===================================================================================
138 std::string Factory::ExtractPackageName(const std::string &name,
144 std::string::size_type slash_position = name.find_last_of("/\\");
145 if (slash_position != std::string::npos)
147 pkgname = name.substr(slash_position+1,std::string::npos);
148 path = name.substr(0,slash_position);
149 // std::cout << "F:P='"<<path<<"'"<<std::endl;//+1,std::string::npos);
156 // remove {.so | dll} if any
157 std::string::size_type dot_position = pkgname.find_last_of('.');
158 if (dot_position != std::string::npos){
159 pkgname = pkgname.substr(0,dot_position);
161 #if defined(__GNUC__)
164 // shared lib name = libbb<name>.so
166 // remove {libbb} if any
167 if (memcmp ( pkgname.c_str(), "libbb", 5) == 0) {
168 pkgname = pkgname.substr(5, pkgname.length());
171 /// \ \todo what would happen if (stupid) user names his package 'libbb' ?!?
172 /// \ --> Should be forbidden!
174 #elif defined(_WIN32)
177 // shared lib name = <name>.dll
179 // remove {bb} if any
180 if (memcmp (pkgname.c_str(), "bb", 2) == 0) {
181 pkgname = pkgname.substr(2, pkgname.length());
185 /// \ \todo what would happen if (stupid) user names his package 'bb' ?!?
186 /// \ --> Should be forbidden!
189 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
194 // ===================================================================================
196 std::string Factory::ExpandLibName(const std::string &name, bool verbose)
198 // ----- Think of expanding path name ( ./ ../ ../../ )
200 char buf[2048]; // for getcwd
201 char * currentDir = getcwd(buf, 2048);
202 std::string cwd(currentDir);
203 std::string libname(name);
205 // tooHigh : true is user supplies a library pathname with too many "../"
206 bool tooHigh = false;
208 if ( name[0] == '/' || name[0] == '\\' )
213 else if (name[0] == '.' && (name[1] == '/' || name[1] == '\\') )
215 libname = cwd + ConfigurationFile::GetInstance().Get_file_separator () + name.substr(2, name.length());
218 else if ( name[0] == '.' && name[1] == '.' && (name[2] == '/' || name[2] == '\\') )
220 if ( IsAtRoot(cwd) ) // hope it gets / (for Linux), C: D: (for Windows)
222 // if we are already at / or c: --> hopeless
224 std::cout << " File path [" << name << "] doesn't exist" << std::endl;
229 // iterate on ../ and go up from the current working dir!
231 bool alreadyProcessRoot = false;
234 std::string::size_type slash_position = cwd.find_last_of(ConfigurationFile::GetInstance().Get_file_separator ());
235 if (slash_position != std::string::npos) {
236 if (slash_position == 0)
238 cwd = cwd.substr(0,slash_position/*+1*/);
239 a = a.substr(3, name.length()); // remove ../
240 if (a == "" || alreadyProcessRoot)
243 std::cout << " File path [" << name << "] doesn't exist" << std::endl;
248 char c = cwd[cwd.size()-1];
249 if (c != '/' && c != '\\' )
250 libname += ConfigurationFile::GetInstance().Get_file_separator ();
253 if ( a[0] != '.' ) // if . (probabely ../), loop again
257 alreadyProcessRoot = true;
259 } // end iterating on ../
263 // std::cout << "=======================================3 libname [" << libname << "]" << std::endl;
267 } // ----- End of expanding path name ( ./ ../ ../../ )
269 return(""); // will never get here!
272 // ===================================================================================
274 std::string Factory::MakeLibnameFromPath(std::string path, std::string pkgname)
276 std::string libname = path;
277 char c = path[path.size()-1];
278 #if defined(__GNUC__)
284 #elif defined(_WIN32)
286 libname = path+"\\bb";
293 // ===================================================================================
296 bool Factory::IsAtRoot(std::string cwd)
298 if ( cwd == "/" // hope it gets / (for Linux)
299 || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
304 // ===================================================================================
306 bool Factory::DoLoadPackage(std::string libname,
312 #if defined(__GNUC__)
315 handler = dlopen(libname.c_str(),
316 BBTK_RTLD_TIME | BBTK_RTLD_SCOPE );
320 std::cout <<"[" <<libname<<"] can't be open" << std::endl;
321 std::cout << " " <<dlerror() << std::endl;
323 return false; // try next path
327 std::cout <<" -->[" <<libname<<"] found" << std::endl;
329 // Loads the Package accessor
331 std::string getpackname(pkgname);
332 getpackname += "GetPackage";
333 void *getpack = dlsym(handler, getpackname.c_str());
337 bbtkError("GetPackage : could not load package \""<<pkgname
338 <<"\" [symbol "<<getpackname<<"] :"<<dlerror());
341 // Verifies that the Package delete function is present
342 std::string delfname(pkgname);
343 delfname += "DeletePackage";
344 void *delf = dlsym(handler, delfname.c_str());
348 bbtkError("DeletePackage : could not load package \""<<pkgname
349 <<"\" [symbol "<<delfname<<"] :"<<dlerror());
352 #elif defined(_WIN32)
357 handler = LoadLibrary(libname.c_str());
360 std::cout <<" no handler for [" <<libname<<"];" << std::endl;
361 return false;// Problem with the found library
364 std::cout <<" --->[" <<libname<<"] found" << std::endl;
366 // Loads the Package accessor
368 std::string getpackname(pkgname);
369 getpackname += "GetPackage";
370 void *getpack = GetProcAddress(handler, getpackname.c_str());
373 FreeLibrary(handler);
374 bbtkError("[1]could not load package \""<<pkgname
375 <<"\" : "<<getpackname<<" symbol not found (is it a bbtk package lib ?)");
376 // look how to get the error message on win
380 // Verifies that the Package delete function is present
381 std::string delfname(pkgname);
382 delfname += "DeletePackage";
383 void *delf = GetProcAddress(handler, delfname.c_str());
386 FreeLibrary(handler);
387 bbtkError("[2]could not load package \""<<pkgname
388 <<"\" : "<<delfname<<" symbol not found (is it a bbtk package lib ?)");
389 // look how to get the error message on win
393 bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
396 // Stores the package
397 PackageInfoType pack;
398 pack.mDynamicLibraryHandler = handler;
399 // Invokes the accessor to the PackageUnit pointer
400 pack.mPackage = ((PackageAccessor)getpack)();
402 mPackageMap[pkgname] = pack;
404 // Test bbtk build version ok
405 if ( pack.mPackage->GetBBTKVersion() != bbtk::GetVersion() )
407 std::string v(pack.mPackage->GetBBTKVersion());
408 UnLoadPackage(pkgname);
409 bbtkError(" package build with bbtk version "
411 << " whereas application build with version "
412 << bbtk::GetVersion());
415 std::string separator =
416 ConfigurationFile::GetInstance().Get_file_separator ();
417 //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
418 std::string docreldoc = separator + "packages" + separator + pkgname
419 + separator + "bbdoc" + separator + "index.html";
420 std::string reldoc = ".." + separator + ".." + separator
422 std::string doc = path + separator + ".." + separator
423 + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH)
425 std::cout << "doc='"<<doc<<"'"<<std::endl;
427 pack.mPackage->SetDocURL(doc);
428 pack.mPackage->SetDocRelativeURL(reldoc);
430 //===================================================================
431 bbtkMessage("Output",2,pack.mPackage->GetName()<<" "
432 <<pack.mPackage->GetVersion()
434 <<pack.mPackage->GetBBTKVersion()<<") "
435 <<pack.mPackage->GetAuthor()
437 bbtkMessage("Output",2,pack.mPackage->GetDescription()<<std::endl);
438 //===================================================================
440 bbtkDebugDecTab("Core",7);
444 //===================================================================
445 /// \brief Loads a package.
447 /// The name is the system-independant name of the package (the name of the instance of bbtk::Package).
448 /// Tries to open the dynamic library :
449 /// - "libbb<name>.so" for linux systems,
450 /// - "bb<name>.dll" for windows systems.
451 /// If it succeeds, then tries to load the symbols "<name>GetPackage" and "<name>DeletePackage".
452 /// "<name>GetPackage" is called to get the pointer on the bbtk::Package of the library
453 /// ("<name>DeletePackage" is not used, its presence is just checked before loading the package).
455 /// now, filename is only the last name (no longer the full name!)
456 /// it will be searched within *all* the paths given in bbtk_config.xml
458 /// verbose = true (set by "config v") displays the loading process
459 void Factory::LoadPackage( const std::string& name,
460 bool use_configuration_file, bool verbose)
462 // Note : in the following :
463 // name : the user supplied name
464 // - abreviated name e.g. pkg pkg.so libbpkg libbbpkg.so
465 // - relative full name e.g. ./libbbpkg.so ../../libbbpkg.so
466 // - absolute full name e.g. /home/usrname/proj/lib/libbbpkg.so
467 // same for Windows, with c:, d: ...
469 bbtkDebugMessageInc("Core",7,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
470 bbtkMessage("Debug",1,"Factory::LoadPackage(\""<<name<<"\")"<<std::endl);
471 bbtkMessage("Debug",1,"use_configuration_file ["
472 << use_configuration_file << "]" << std::endl);
474 std::vector<std::string> package_paths;
475 std::string libname; // full path library name
476 std::string pkgname; // e.g. libbb<pkgname>.so
479 pkgname = ExtractPackageName(name,upath);
481 bbtkMessage("Debug",1,"Package name ["<<pkgname<<"]"<<std::endl);
482 bbtkMessage("Debug",1,"Package path ["<<upath<<"]"<<std::endl);
484 // no loading package if already loaded
485 PackageMapType::iterator iUnload;
486 iUnload = mPackageMap.find(pkgname);
487 if (iUnload != mPackageMap.end())
489 bbtkMessage("Output",2,"["<<pkgname<<"] already loaded"<<std::endl);
493 // If path provided by user will be the first scanned :
494 // push it into vector of paths
495 if (upath.length()>0) package_paths.push_back(upath);
497 // Add the path of config file
498 if (use_configuration_file)
500 std::vector<std::string>::const_iterator pi;
501 for (pi =ConfigurationFile::GetInstance().Get_package_paths().begin();
502 pi!=ConfigurationFile::GetInstance().Get_package_paths().end();
504 package_paths.push_back(*pi);
509 bool foundFile = false;
511 std::vector<std::string>::iterator i;
512 for (i=package_paths.begin();i!=package_paths.end();++i)
515 std::string path = *i;
517 // we *really* want '.' to be the current working directory
519 char buf[2048]; // for getcwd
520 char * currentDir = getcwd(buf, 2048);
521 std::string cwd(currentDir);
525 libname = MakeLibnameFromPath(path, pkgname);
527 bbtkMessage("Debug",2,"-> Trying to load ["<<libname<<"]"<<std::endl);
529 // Check if library exists
530 if ( !FileExists(libname) )
532 // The following is *NOT* a debug time message :
533 // It's a user intended message.
534 // Please don't remove it.
536 std::cout <<" [" <<libname <<"] : doesn't exist" <<std::endl;
537 continue; // try next path
541 // Try to Load the library
543 ok = DoLoadPackage( libname, pkgname, path, verbose);
546 bbtkMessage("Debug",2," OK"<<std::endl);
547 break; // a package was found; we stop iterating
549 } //------------------ // end for ( package_paths.begin();i!=package_paths.end() )
552 if( !ok ) // nothing was loaded
556 bbtkError("could not find package ["<<pkgname<< "]");
560 #if defined(__GNUC__)
561 bbtkError("could not load package \""<< pkgname
562 <<"\" :" << std::endl << " " <<dlerror());
563 #elif defined(_WIN32)
564 bbtkError("could not load package \""<<pkgname
565 <<"\" : " << std::endl << " " <<libname<<" not found");
567 // look how to get the error message on win
569 // it is the bordel !! (the bloody fucking bordel, you mean?)
570 // look : http://msdn2.microsoft.com/en-us/library/ms680582.aspx
574 bbtkMessage("Output",2,"[" << libname << "] loaded" << std::endl);
578 //===================================================================
579 /// \brief UnLoads a package.
581 /// The package must have been previously loaded by LoadPackage.
582 /// If the entry is found in the map, calls ClosePackage
583 void Factory::UnLoadPackage( const std::string& userSuppliedName )
586 std::string name = ExtractPackageName(userSuppliedName,path);
587 bbtkDebugMessageInc("Core",7,"Factory::UnLoadPackage(\""
588 <<name<<"\")"<<std::endl);
590 PackageMapType::iterator i;
591 i = mPackageMap.find(name);
592 if (i == mPackageMap.end())
594 bbtkError("cannot unload package \""<<name
595 <<"\" : package not loaded !");
598 bbtkDebugDecTab("Core",7);
600 //===================================================================
603 //===================================================================
604 /// \brief Close the package referenced by the iterator
606 /// If it is a dynamically loaded package
607 /// - Loads and calls the function "<name>DeletePackage" of the dynamic library (responsible for package desallocation)
608 /// - Closes the dynamic library
609 /// - Erases the package entry in the packages map
611 /// Else simply erases the package entry in the packages map
612 void Factory::ClosePackage(PackageMapType::iterator& i)
614 bbtkDebugMessageInc("Core",7,"Factory::ClosePackage(\""
615 <<i->second.mPackage->GetName()
618 if (i->second.mDynamicLibraryHandler)
621 // If it is a dynamically loaded package
622 // Loads the Package delete function
624 std::string delfname(i->second.mPackage->GetName());
625 delfname += "DeletePackage";
626 #if defined(__GNUC__)
627 void *delf = dlsym(i->second.mDynamicLibraryHandler, delfname.c_str());
630 bbtkError("could not close package \""
631 <<i->second.mPackage->GetName()
632 <<"\" :"<<dlerror());
634 #elif defined(_WIN32)
635 void *delf = GetProcAddress(i->second.mDynamicLibraryHandler,
639 bbtkError("could not close package \""
640 <<i->second.mPackage->GetName()
642 <<" symbol not found (how did you open it ???");
643 //<<"\" :"<<dlerror());
647 // deletes the package
648 ((PackageDeleteFunction)delf)();
650 // closes the dl handler
651 #if defined(__GNUC__)
652 dlclose(i->second.mDynamicLibraryHandler);
653 #elif defined(_WIN32)
655 FreeLibrary(i->second.mDynamicLibraryHandler);
660 // If it is a manually inserted package
661 delete i->second.mPackage;
664 // remove the entry in the map
665 mPackageMap.erase(i);
666 bbtkDebugDecTab("Core",7);
668 //===================================================================
672 //===================================================================
673 /// Displays the list of packages loaded
674 void Factory::PrintPackages(bool details, bool adaptors) const
676 bbtkDebugMessageInc("Core",9,"Factory::PrintPackages"<<std::endl);
678 PackageMapType::const_iterator i;
679 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
681 bbtkMessage("Help",1, i->first << std::endl);
683 i->second.mPackage->PrintBlackBoxes(false,adaptors);
687 bbtkDebugDecTab("Core",9);
689 //===================================================================
691 //===================================================================
692 /// Displays help on a package
693 void Factory::HelpPackage(const std::string& name/* &userSuppliedName */, bool adaptors) const
695 // std::string name = ExtractPackageName(userSuppliedName);
696 bbtkDebugMessageInc("Core",9,"Factory::HelpPackage(\""<<name<<"\")"
699 PackageMapType::const_iterator i = mPackageMap.find(name);
700 if ( i != mPackageMap.end() )
702 bbtkMessage("Help",1, "Package "<<i->first<<" ");
703 if (i->second.mPackage->GetVersion().length()>0)
704 bbtkMessageCont("Help",1,"v" <<i->second.mPackage->GetVersion());
705 if (i->second.mPackage->GetAuthor().length()>0)
706 bbtkMessageCont("Help",1,"- "<<i->second.mPackage->GetAuthor());
707 bbtkMessageCont("Help",1,std::endl);
708 bbtkIncTab("Help",1);
709 bbtkMessage("Help",1,i->second.mPackage->GetDescription()<<std::endl);
710 if (i->second.mPackage->GetNumberOfBlackBoxes()>0)
712 bbtkMessage("Help",1, "Black boxes : "<<std::endl);
713 i->second.mPackage->PrintBlackBoxes(true,adaptors);
717 bbtkMessage("Help",1, "No black boxes"<<std::endl);
719 bbtkDecTab("Help",1);
723 bbtkDebugDecTab("Core",9);
724 bbtkError("package \""<<name<<"\" unknown");
727 bbtkDebugDecTab("Core",9);
729 //===================================================================
731 //===================================================================
732 /// Prints help on the black box of type <name>
733 void Factory::HelpBlackBox(const std::string& name, bool full) const
735 bbtkDebugMessageInc("Core",9,"Factory::HelpBlackBox(\""<<name<<"\")"
739 PackageMapType::const_iterator i;
740 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
742 if (i->second.mPackage->ContainsBlackBox(name))
744 i->second.mPackage->HelpBlackBox(name,full);
749 bbtkDebugDecTab("Core",9);
752 bbtkError("No package of the factory contains any black box <"
756 //===================================================================
759 //===================================================================
760 /// Inserts a package in the factory
761 void Factory::InsertPackage( Package* p )
763 bbtkDebugMessageInc("Core",9,"Factory::InsertPackage(\""<<
764 p->GetName()<<"\")"<<std::endl);
766 PackageInfoType pack;
767 pack.mDynamicLibraryHandler = 0;
771 mPackageMap[p->GetName()] = pack;
772 bbtkDebugDecTab("Core",9);
774 //===================================================================
776 //===================================================================
777 /// Removes a package from the factory (and deletes it)
778 void Factory::RemovePackage( Package* p )
780 bbtkDebugMessageInc("Core",9,"Factory::RemovePackage(\""<<
781 p->GetName()<<"\")"<<std::endl);
783 PackageMapType::iterator i;
784 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
786 if (i->second.mPackage == p) break;
789 if (i!=mPackageMap.end())
795 bbtkError("Factory::RemovePackage(\""<<
796 p->GetName()<<"\") : package absent from factory");
799 bbtkDebugDecTab("Core",9);
801 //===================================================================
804 //===================================================================
805 /// Creates an instance of a black box of type <type> with name <name>
806 BlackBox* Factory::NewBlackBox(const std::string& type,
807 const std::string& name) const
809 bbtkDebugMessageInc("Core",7,"Factory::NewBlackBox(\""
810 <<type<<"\",\""<<name<<"\")"<<std::endl);
813 PackageMapType::const_iterator i;
814 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
816 b = i->second.mPackage->NewBlackBox(type,name);
821 bbtkError("black box type \""<<type<<"\" unknown");
824 bbtkDebugDecTab("Core",7);
827 //===================================================================
829 //===================================================================
830 /// Creates an instance of a black box of type <type> with name <name>
831 BlackBox* Factory::NewAdaptor(TypeInfo typein,
833 const std::string& name) const
835 bbtkDebugMessageInc("Core",8,"Factory::NewAdaptor(<"
836 <<TypeName(typein)<<">,<"
837 <<TypeName(typeout)<<">,\""
838 <<name<<"\")"<<bbtkendl);
842 PackageMapType::const_iterator i;
843 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
845 b = i->second.mPackage->NewAdaptor(typein,typeout,name);
851 <<TypeName(typein)<<"> to <"
853 <<"> adaptor available");
856 bbtkDebugDecTab("Core",7);
859 //===================================================================
861 //===================================================================
862 /// Creates an instance of a connection
863 Connection* Factory::NewConnection(BlackBox* from,
864 const std::string& output,
866 const std::string& input) const
868 bbtkDebugMessage("Core",7,"Factory::NewConnection(\""
869 <<from->bbGetName()<<"\",\""<<output<<"\",\""
870 <<to->bbGetName()<<"\",\""<<input
873 return new Connection(from,output,to,input);
876 // !!! WARNING : WE NEED TO TEST THE TYPE NAME EQUALITY
877 // BECAUSE IN DIFFERENT DYN LIBS THE type_info EQUALITY CAN
878 // BE FALSE (DIFFERENT INSTANCES !)
880 std::string t1 ( from->bbGetOutputType(output).name() );
881 std::string t2 ( to->bbGetInputType(input).name() );
885 //from->bbGetOutputType(output) ==
886 // to->bbGetInputType(input) )
888 c = new Connection(from,output,to,input);
892 // std::cout << "Adaptive connection "<<std::endl;
894 name = from->bbGetName() + "." + output + "-"
895 + to->bbGetName() + "." + input;
898 PackageMapType::const_iterator i;
899 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
901 b = i->second.mPackage->NewAdaptor(from->bbGetOutputType(output),
902 to->bbGetInputType(input),
908 bbtkError("did not find any <"
909 <<TypeName(from->bbGetOutputType(output))
911 <<TypeName(to->bbGetInputType(input))
914 c = new AdaptiveConnection(from,output,to,input,b);
916 bbtkDebugDecTab("Core",7);
921 //===================================================================
925 //===================================================================
926 const Package* Factory::GetPackage(const std::string& name) const
928 bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
931 PackageMapType::const_iterator i = mPackageMap.find(name);
932 if ( i != mPackageMap.end() )
934 bbtkDebugDecTab("Core",9);
935 return i->second.mPackage;
939 bbtkDebugDecTab("Core",9);
940 bbtkError("package \""<<name<<"\" unknown");
943 bbtkDebugDecTab("Core",9);
945 //===================================================================
947 //===================================================================
948 Package* Factory::GetPackage(const std::string& name)
950 bbtkDebugMessageInc("Core",9,"Factory::GetPackage(\""<<name<<"\")"
953 PackageMapType::const_iterator i = mPackageMap.find(name);
954 if ( i != mPackageMap.end() )
956 bbtkDebugDecTab("Core",9);
957 return i->second.mPackage;
961 bbtkDebugDecTab("Core",9);
962 bbtkError("package \""<<name<<"\" unknown");
965 bbtkDebugDecTab("Core",9);
967 //===================================================================
969 //===================================================================
970 void Factory::WriteDotFilePackagesList(FILE *ff)
972 bbtkDebugMessageInc("Core",9,"Factory::WriteDotFilePackagesList()"
976 fprintf( ff , "subgraph cluster_FACTORY {\n");
977 fprintf( ff , " label = \"PACKAGES\"%s\n", ";");
978 fprintf( ff , " style=filled%s\n",";");
979 fprintf( ff , " color=lightgrey%s\n",";");
980 fprintf( ff , " rankdir=TB%s\n",";");
982 PackageMapType::const_iterator i;
983 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
985 std::string url = GetPackage(i->first)->GetDocURL();
986 fprintf(ff," %s [shape=ellipse, URL=\"%s\"]%s\n",
990 fprintf( ff , "}\n\n");
991 bbtkDebugDecTab("Core",9);
993 //===================================================================
996 void Factory::ShowGraphTypes(const std::string& name) const
999 PackageMapType::const_iterator i;
1000 for (i = mPackageMap.begin(); i!=mPackageMap.end(); ++i )
1002 if (i->second.mPackage->ContainsBlackBox(name))
1004 std::string separator = ConfigurationFile::GetInstance().Get_file_separator ();
1006 // Don't pollute the file store with "doc_tmp" directories ...
1007 std::string default_doc_dir = ConfigurationFile::GetInstance().Get_default_doc_tmp();
1008 std::string directory = "\"" + default_doc_dir + separator + "doc_tmp" +separator + "\"";
1009 std::string filename2 = default_doc_dir + separator + "doc_tmp" + separator + "tmp.html";
1012 std::string command("start \"Titre\" /D ");
1014 std::string command("gnome-open ");
1016 command=command + directory +" tmp.html";
1018 ff=fopen(filename2.c_str(),"w");
1020 fprintf(ff,"<html><head><title>TMP</title> <script type=\"text/javascript\"> <!--\n");
1021 fprintf(ff," window.location=\"%s#%s\";\n" , i->second.mPackage->GetDocURL().c_str(),name.c_str() );
1022 fprintf(ff,"//--></script></head><body></body></html>\n");
1025 //fprintf(ff, "<a href=\"%s#%s\">Link</a>\n", i->second.mPackage->GetDocURL().c_str(),name.c_str() );
1027 system( command.c_str() );
1032 bbtkDebugDecTab("Core",9);
1035 bbtkError("No package of the factory contains any black box <"