/*========================================================================= Program: bbtk Module: $RCSfile: bbtkPackage.cxx,v $ Language: C++ Date: $Date: 2010/09/12 14:52:25 $ Version: $Revision: 1.35 $ =========================================================================*/ /* --------------------------------------------------------------------- * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale) * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux * * This software is governed by the CeCILL-B license under French law and * abiding by the rules of distribution of free software. You can use, * modify and/ or redistribute the software under the terms of the CeCILL-B * license as circulated by CEA, CNRS and INRIA at the following URL * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html * or in the file LICENSE.txt. * * As a counterpart to the access to the source code and rights to copy, * modify and redistribute granted by the license, users are provided only * with a limited warranty and the software's author, the holder of the * economic rights, and the successive licensors have only limited * liability. * * The fact that you are presently reading this means that you have had * knowledge of the CeCILL-B license and that you accept its terms. * ------------------------------------------------------------------------ */ /** *\file *\brief Class bbtk::Package : registers black boxes descriptors and is able to create instances of the black boxes registered. */ #include "bbtkPackage.h" #include "bbtkComplexBlackBoxDescriptor.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) { bbtkDebugMessage("object",1,"##> Package::New('"< Package('"< ~Package(\""<GetName(); bbtkDebugMessage("package",5,"--- Releasing descriptor '" <GetDescriptorMap().find(descname); if (desc == pack.lock()->GetDescriptorMap().end()) { bbtkDebugMessage("package",5, " Descriptor has already been released" <second; desc->second.reset(); // if it is dead : remove it if (pdesc.expired()) { bbtkDebugMessage("package",2," ==> '"<GetDescriptorMap().find(descname); if (desc != pack.lock()->GetDescriptorMap().end()) pack.lock()->GetDescriptorMap().erase(desc); } else { //pdesc.expired bbtkDebugMessage("package",5," ... Descriptor still alive (" <GetDescriptorMap()[descname] = pdesc.lock(); } // pdesc.expired } //========================================================================== //========================================================================== /// 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()->GetDescriptorMap().size(); long nrefs = pack.use_count(); bbtkDebugMessage("package",5," "< No more external ref : checking descriptors" < descnamelist; DescriptorMapType::iterator i; for (i=pack.lock()->mDescriptorMap.begin(); i!= pack.lock()->mDescriptorMap.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",1,"--- Package::Release('"<< packname <<"') : package expired during release : bailing out"<mDescriptorMap[*descname]; if ( (dyn==0) || (boost::dynamic_pointer_cast(desc)) ) { PackageReleaseBlackBoxDescriptorInternal(pack,*descname); } #else PackageReleaseBlackBoxDescriptorInternal(pack,*descname); #endif } // UnLoadDynamicLibrary(pack); // Unload orphan dl packages Package::UnLoadReleasedDynamicallyLoadedPackages(); } #ifdef BBTK_COMPILE_DEBUG_MESSAGES bbtkDebugMessage("package",2,"<== Package::Release('"<< packname<<"')"<mDynamicLibraryHandler ? 1:0; long ndesc = pack.lock()->GetDescriptorMap().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<<"','"< 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",2,"<== Package::CreateFromDynamicLibrary(" <mDynamicLibraryHandler)) return; std::string packname = pack.lock()->GetName(); bbtkDebugMessage("package",5,"==> Package::UnLoadDynamicLibrary('" <GetDescriptorMap().empty()) { bbtkDebugMessage("package",5," Package not empty ... abort" < dynamic library for package '" < package '"< Package::UnLoadReleasedDynamicallyLoadedPackages()"<::iterator i; //JCP- 21-04-09 if(mReleasedDynamicallyLoadedPackages.size()>0){ for (i=mReleasedDynamicallyLoadedPackages.begin(); i!=mReleasedDynamicallyLoadedPackages.end(); ++i) { if (!i->expired()) UnLoad(*i); } } //JCP- 21-04-09 bbtkDebugMessage("package",5,"<== Package::UnLoadReleasedDynamicallyLoadedPackages()"<GetName(); bbtkDebugMessage("package",6,"==> Package::UnLoad("<mDynamicLibraryHandler; // deletes the package p->mDLDeletePackageFunction(); // closes the dl handler #if defined(__GNUC__) if (dlclose(h)!=0) { printf("EED Package::UnLoad ERROR %s\n", packname.c_str() ); bbtkWarning("Failed to close dynamic library for package '"< dynamic library for package '" < 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::Register(BlackBoxDescriptor::Pointer d) { bbtkDebugMessageInc("kernel",8,"Package<"<::Register(\""<GetTypeName()<<"\")"<GetTypeName()); if (i!=mDescriptorMap.end()) { bbtkWarning("Package<"< : Trying to register box type <" <GetTypeName()<<"> which is already in the package"); return false; } mDescriptorMap[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<"<::Register(\""<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<"<::Register(\""<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::Check() const { bbtkMessage("debug",1,"****** Checking Package "<<(void*)this <<" ["<second->Check(true); } bbtkMessage("debug",1,"****** Checking Package "<<(void*)this <<" ["<::ChangeDescriptorName(\""< does not contains the black box <"<"); } i->second->SetTypeName(newname); mDescriptorMap[newname] = i->second; mDescriptorMap.erase(i); bbtkDebugDecTab("kernel",8); } //========================================================================== //========================================================================== void Package::PrintHelpListDescriptors(bool description, bool adaptors) const { unsigned int lmax = 0; std::vector names; std::vector kinds; std::vector descrs; DescriptorMapType::const_iterator i; for (i=mDescriptorMap.begin(); i!=mDescriptorMap.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::PrintHelpListAdaptors(bool description) const { DescriptorMapType::const_iterator i; for (i=mDescriptorMap.begin(); i!=mDescriptorMap.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 descriptor void Package::PrintHelpDescriptor(const std::string& name, bool full) const { bbtkDebugMessageInc("kernel",8,"Package<"<::PrintHelpDescriptor(\"" < 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::ContainsDescriptor(const std::string& name) const { bbtkDebugMessageInc("kernel",8,"Package<"<::ContainsDescriptor(\"" <::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"; } //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1225"<\n"; s << "

Black Boxes : \n"; s << "

    \n"; s << "

    \n"; DescriptorMapType::const_iterator i; //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1236"<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); //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1246"<"; 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"; //std::cout<<"JCP bbtkPackage.cxx void Package::CreateHtmlPage() ln 1268"<\n"; for (i=mDescriptorMap.begin(); i!=mDescriptorMap.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=mDescriptorMap.begin(); i!=mDescriptorMap.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; //========================================================================== }