/*========================================================================= Program: bbtk Module: $RCSfile: bbtkPackage.cxx,v $ Language: C++ Date: $Date: 2008/04/22 08:29:09 $ Version: $Revision: 1.15 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See doc/license.txt or http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ /** *\file *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered. */ #include "bbtkPackage.h" #include "bbtkMessageManager.h" #include "bbtkConfigurationFile.h" #include #include #include "bbtkUtilities.h" namespace bbtk { //========================================================================== /// Creates a new package Package::Pointer Package::New(const std::string& name, const std::string& author, const std::string& description, const std::string& version, const std::string& BBTKVersion) { bbtkDebugMessage("object",1,"##> Package::New('"< Package::Package('"< Package::~Package(\""<GetName(); Package::BlackBoxMapType::iterator desc = pack.lock()->GetBlackBoxMap().find(descname); if (desc == pack.lock()->GetBlackBoxMap().end()) { bbtkDebugMessage("package",3, " Descriptor has already been released" <second; desc->second.reset(); // if it is dead : remove it if (pdesc.expired()) { bbtkDebugMessage("package",2," '"<GetBlackBoxMap().find(descname); if (desc != pack.lock()->GetBlackBoxMap().end()) pack.lock()->GetBlackBoxMap().erase(desc); } else { bbtkDebugMessage("package",3," ... Descriptor still alive (" <GetBlackBoxMap()[descname] = pdesc.lock(); } } //========================================================================== //========================================================================== /// Release void Package::Release(Package::WeakPointer pack) { std::string packname = pack.lock()->mName; bbtkDebugMessage("package",1,"==> Package::Release('"<< packname<<"')"<mDynamicLibraryHandler ? 1:0; long ndesc = pack.lock()->GetBlackBoxMap().size(); long nrefs = pack.use_count(); bbtkDebugMessage("package",2," "< No more external ref : checking descriptors" < descnamelist; BlackBoxMapType::iterator i; for (i=pack.lock()->mBlackBoxMap.begin(); i!= pack.lock()->mBlackBoxMap.end(); ++i) descnamelist.push_back(i->first); // Iterator over the initial names std::vector::iterator descname; for (descname=descnamelist.begin(); descname!=descnamelist.end(); ++descname) { // Is package still alive ? if (pack.expired()) { bbtkDebugMessage("package",2,"--- Package::Release('"<< packname <<"') : package expired during release : bailing out"<mDynamicLibraryHandler ? 1:0; long ndesc = pack.lock()->GetBlackBoxMap().size(); long nrefs = pack.use_count(); bbtkDebugMessage("package",1," ... Package still alive (" <mName; std::string dname = descr.lock()->GetTypeName(); bbtkDebugMessage("package",3,"==> Package::ReleaseBlackBoxDescriptor('"<< packname<<"','"<mDynamicLibraryHandler ? 1:0; long ndesc = pack.lock()->GetBlackBoxMap().size(); long nrefs = pack.use_count(); bbtkDebugMessage("package",3," "<mDynamicLibraryHandler ? 1:0; long ndesc = pack.lock()->GetBlackBoxMap().size(); long nrefs = pack.use_count(); bbtkDebugMessage("package",3," ... Package still alive (" < Package::OpenDynamicLibrary(" < Package::CreateFromDynamicLibrary(" <mDynamicLibraryHandler = h; p->mDLDeletePackageFunction = df; std::string separator = ConfigurationFile::GetInstance().Get_file_separator (); //BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH) std::string docreldoc = separator + "bbdoc" + separator + pkgname + separator + "index.html"; std::string reldoc = ".." + separator + ".." + docreldoc; std::string doc = path + separator + ".." + separator + BBTK_STRINGIFY_SYMBOL(BBTK_DOC_REL_PATH) + docreldoc; p->SetDocURL(doc); p->SetDocRelativeURL(reldoc); bbtkDebugMessage("package",1,"<== Package::CreateFromDynamicLibrary(" <mDynamicLibraryHandler)) return; std::string packname = pack.lock()->GetName(); bbtkDebugMessage("package",3,"==> Package::UnLoadDynamicLibrary('" <GetBlackBoxMap().empty()) { bbtkDebugMessage("package",3," Package not empty ... abort" < Package::UnLoadReleasedDynamicallyLoadedPackages()"<::iterator i; for (i=mReleasedDynamicallyLoadedPackages.begin(); i!=mReleasedDynamicallyLoadedPackages.end(); ++i) { if (!i->expired()) UnLoad(*i); } bbtkDebugMessage("package",2,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<GetName(); bbtkDebugMessage("package",2,"==> Package::UnLoad("<mDynamicLibraryHandler; // deletes the package p->mDLDeletePackageFunction(); // closes the dl handler #if defined(__GNUC__) dlclose(h); #elif defined(_WIN32) FreeLibrary(h); #endif bbtkDebugMessage("package",2," ... dynamic library unloaded"< with name BlackBox::Pointer Package::NewBlackBox(const std::string& type, const std::string& name) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::NewBlackBox(\""<second->NewBlackBox(name); bbtkDebugDecTab("Kernel",8); return bb; } //========================================================================== //========================================================================== /// Creates an instance of an adaptor of input type and /// output type with name BlackBox::Pointer Package::NewAdaptor(const DataInfo& typein, const DataInfo& typeout, const std::string& name) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::NewAdaptor(" <second.lock()->NewBlackBox(name); bbtkDebugDecTab("Kernel",8); return bb; } //========================================================================== //========================================================================== /// Creates an instance of an adaptor of input type and /// output type with name BlackBox::Pointer Package::NewWidgetAdaptor(const DataInfo& typein, const DataInfo& typeout, const std::string& name) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::NewWidgetAdaptor(" <second.lock()->NewBlackBox(name); bbtkDebugDecTab("Kernel",8); return bb; } //========================================================================== //========================================================================== /// Returns true is the package contains /// an adaptor of input type and /// output type /// If successfull then adaptor contains the black box type name bool Package::FindWidgetAdaptor(const DataInfo& typein, const DataInfo& typeout, std::string& adaptor) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::FindWidgetAdaptor(" <second.lock()->GetTypeName(); bbtkDebugDecTab("Kernel",8); return true; } //========================================================================== //========================================================================== /// Returns true is the package contains /// an adaptor of input type and /// output type /// If successfull then adaptor contains the black box type name bool Package::FindAdaptor(const DataInfo& typein, const DataInfo& typeout, std::string& adaptor) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::FindAdaptor(" <second.lock()->GetTypeName(); bbtkDebugDecTab("Kernel",8); return true; } //========================================================================== //========================================================================== /// Registers a black box descriptor in the package bool Package::RegisterBlackBox(BlackBoxDescriptor::Pointer d) { bbtkDebugMessageInc("Kernel",8,"Package<"<::RegisterBlackBox(\""<GetTypeName()<<"\")"<GetTypeName()); if (i!=mBlackBoxMap.end()) { bbtkWarning("Package<"< : Trying to register box type <" <GetTypeName()<<"> which is already in the package"); return false; } mBlackBoxMap[d->GetTypeName()] = d; // d->Reference(); d->SetPackage(GetThisPointer()); // If it is a default adaptor, also register it in the adaptors map if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR ) { bbtkDebugMessage("Kernel",8,"Package<"<::RegisterBlackBox(\""<GetTypeName()<<"\") : The box is an adaptor, inserting it in adaptors map ..."<GetInputDescriptor("In")->GetTypeInfo(); TypeInfo typeout = d->GetOutputDescriptor("Out")->GetTypeInfo(); DataInfo infoin(typein,d->GetInputDescriptor("In")->GetNature()); DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature()); AdaptorKey key(infoin,infoout,d->GetKind()); AdaptorMapType::const_iterator i; i = mAdaptorMap.find(key); if (i == mAdaptorMap.end()) { mAdaptorMap[key] = d; } // If already an adaptor registered : error else { if (i->second.lock()->GetTypeName() != d->GetTypeName()) { bbtkError("Package <"< : trying to register black box <" <GetTypeName() <<"> as default adaptor but there is already a default adaptor registered (<" <second.lock()->GetTypeName()<<">)"); } } } // If it is a default adaptor, also register it in the adaptors map else if ( d->GetKind() == BlackBoxDescriptor::DEFAULT_GUI) { bbtkDebugMessage("Kernel",8,"Package<"<::RegisterBlackBox(\""<GetTypeName()<<"\") : The box is a widget adaptor, inserting it in adaptors map ..."<GetOutputDescriptor("Out")->GetTypeInfo(); DataInfo infoin(typeid(void),""); DataInfo infoout(typeout,d->GetOutputDescriptor("Out")->GetNature()); AdaptorKey key(infoin,infoout,d->GetKind()); AdaptorMapType::const_iterator i; i = mAdaptorMap.find(key); if (i == mAdaptorMap.end()) { mAdaptorMap[key] = d; } // If already an adaptor registered : error else { if (i->second.lock()->GetTypeName() != d->GetTypeName()) { bbtkError("Package <"< : trying to register black box <" <GetTypeName() <<"> as default widget adaptor but there is already a default adaptor registered (<" <second.lock()->GetTypeName()<<">)"); } } } bbtkDebugDecTab("Kernel",8); return true; } //========================================================================== //=================================================================== void Package::CheckBoxes() const { bbtkMessage("debug",1,"****** Checking Package "<<(void*)this <<" ["<second->Check(true); } bbtkMessage("debug",1,"****** Checking Package "<<(void*)this <<" ["<::ChangeBlackBoxName(\""< does not contains the black box <"<"); } i->second->SetTypeName(newname); mBlackBoxMap[newname] = i->second; mBlackBoxMap.erase(i); bbtkDebugDecTab("Kernel",8); } //========================================================================== //========================================================================== /// Displays the list of black boxes of the package void Package::PrintBlackBoxes(bool description, bool adaptors) const { unsigned int lmax = 0; std::vector names; std::vector kinds; std::vector descrs; BlackBoxMapType::const_iterator i; for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) { if ( adaptors || ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) ) { std::string name(" "); name += i->second->GetTypeName(); names.push_back(name); std::string kind; if ( i->second->GetKind() == BlackBoxDescriptor::ADAPTOR ) { kind = std::string("[A]"); } else if ( i->second->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR ) { kind = std::string("[DA]"); } kinds.push_back(kind); unsigned int l = name.size()+kind.size(); if (l>lmax) lmax = l; std::string descr; if (description) { descr += " : "; descr += i->second->GetDescription(); } descrs.push_back(descr); } } std::string offs; offs.append(lmax+3,' '); std::vector::iterator ni,ci,di; for (ni = names.begin(), ci = kinds.begin(), di = descrs.begin(); ni != names.end(); ++ni, ++ci, ++di) { std::string space; space.append(lmax - ni->size() - ci->size(),' '); bbtkMessage("Help",1,*ni << space << *ci ); std::string d(*di); unsigned int dmax = 75 - lmax; // while (d.size() > dmax ) // { if (d.size()>dmax) bbtkMessage("Help",1,d.substr(0,dmax) << "..." << std::endl); else bbtkMessage("Help",1,d << std::endl); // d = d.substr(dmax,d.size()); // } } } //========================================================================== //========================================================================== /// Displays the list of adaptors of the package void Package::PrintAdaptors(bool description) const { BlackBoxMapType::const_iterator i; for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) { if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD ) { bbtkMessage("Help",1, " "<second->GetTypeName()); if ( i->second->GetKind() == BlackBoxDescriptor::DEFAULT_ADAPTOR ) { bbtkMessage("Help",1, " [default]"); } if (description) { bbtkMessage("Help",1, " : "<second->GetDescription()); } bbtkMessage("Help",1,std::endl); } } /* AdaptorMapType::const_iterator i; for (i=mAdaptorMap.begin(); i!=mAdaptorMap.end(); ++i) { bbtkMessage("Help",1, " "<second->GetTypeName()); if (detail_level>0) { bbtkMessage("Help",1, " : "<second->GetDescription()); } bbtkMessage("Help",1,std::endl); } */ } //========================================================================== //========================================================================== /// Prints help on a black box void Package::HelpBlackBox(const std::string& name, bool full) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::HelpBlackBox(\"" < does not contains the black box <"<"); } // bbtkMessage("Help",1,"["<second->GetHelp(full); bbtkDebugDecTab("Kernel",8); } //========================================================================== //========================================================================== /// Returns true iff the package contains the box of name boxname bool Package::ContainsBlackBox(const std::string& name) const { bbtkDebugMessageInc("Kernel",8,"Package<"<::HelpBlackBox(\"" <::CreateHtmlPage(\"" <\n"; s << "\n"; s << "" << title << "\n"; s << "\n"; s << "\n"; s << "\n"; s << "\n"; // s << "\n"; s << "\n"; //---------------------- //---------------------- // Html body s << "\n"; s << "\n"; //---------------------- // Header if ( custom_header.length() != 0) { if ( custom_header != "none" ) { std::ifstream in; in.open(custom_header.c_str()); if (!in.good()) { bbtkError("Could not open file \""<\n"; /* s << " Warning: " << custom_header <<" could not be embedded.\n"; s << "
\n"; */ } } else { s << "

"<\n"; s << "

\n"; s << "\n"; s << "\n"; s << "\n"; s << "\n"; s << "\n"; s << "
Description : " << GetDescription() << "
Author(s) : " << GetAuthor() << "
Author(s) : " << GetCategory() << "
Version : " << GetVersion() << "
bbtk Version : " << bbtk::GetVersion() << "
\n"; } //------------------- // Table of contents // Black boxes list // s << "

\n"; s << "

Black Boxes : \n"; s << "

    \n"; s << "

    \n"; BlackBoxMapType::const_iterator i; for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) { if ( i->second->GetKind() != BlackBoxDescriptor::STANDARD) continue; std::string name = i->second->GetTypeName(); Utilities::html_format(name); std::string descr = i->second->GetDescription(); Utilities::html_format(descr); s << ""; s << " "; s << " "; s << "\n"; } s << "
    "; s << "   " <"; s << "" << descr << "
    \n"; s << "

\n"; s << "
\n"; //------------------- // Adaptors list if (mAdaptorMap.size()>0) { // s << "
\n"; s << "

Adaptors : \n"; s << "

    \n"; // BlackBoxMapType::const_iterator i; s << "

    \n"; for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end();++i) { if ( i->second->GetKind() == BlackBoxDescriptor::STANDARD) continue; std::string name = i->second->GetTypeName(); Utilities::html_format(name); std::string descr = i->second->GetDescription(); s << ""; s << " "; s << " "; s << "\n"; } s << "
    "; s << "   " <"; s << "" << descr << "
    \n"; s << "

\n"; s << "
\n"; } // s << "
\n"; // s << "


\n"; // s << "\n"; // s << "Top: Top\n"; // s << "Previous: (dir), // s << "Up: (dir) // s << "
\n"; //---------------------- // Boxes doc //------------------- // Computes output directory from filename to pass it to // BlackBoxDescriptor::InsertHtmlHelp std::string dir; std::string::size_type slash_position = filename.find_last_of("/\\"); if (slash_position != std::string::npos) { if (slash_position == 0) slash_position = 1; dir = filename.substr(0,slash_position); } for (i=mBlackBoxMap.begin(); i!=mBlackBoxMap.end(); ++i) { i->second->InsertHtmlHelp(s,detail,level,dir,relative_link); } //---------------------- // Footer time_t rawtime; tm * ptm; time ( &rawtime ); ptm = gmtime ( &rawtime ); s << "


\n"; s << "Automatically generated by "< "//from " // < <<"on " << ptm->tm_mday << "/" << ptm->tm_mon << "/" << ptm->tm_year+1900 << " - " << ptm->tm_hour << ":" << ptm->tm_min << " GMT\n"; s << "\n"; s.close(); //---------------------- // End bbtkDebugDecTab("Kernel",9); } //========================================================================== //========================================================================== std::string Package::GetObjectName() const { return std::string("Package '")+mName+std::string("'"); } //========================================================================== //========================================================================== std::string Package::GetObjectInfo() const { std::stringstream i; i << " - "<second->GetObjectRecursiveSize(); } return s; } //========================================================================== //========================================================================== std::set Package::mReleasedDynamicallyLoadedPackages; //========================================================================== }