00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <algorithm>
00026 #include <iostream>
00027 #include <set>
00028 #include <string>
00029 #include <typeinfo>
00030 #include <vector>
00031
00032 #include "../common/WLogger.h"
00033 #include "combiner/WApplyCombiner.h"
00034 #include "exceptions/WPrototypeNotUnique.h"
00035 #include "exceptions/WPrototypeUnknown.h"
00036 #include "WModule.h"
00037 #include "WModuleCombiner.h"
00038 #include "WModuleFactory.h"
00039
00040
00041 boost::shared_ptr< WModuleFactory > WModuleFactory::m_instance = boost::shared_ptr< WModuleFactory >();
00042
00043 WModuleFactory::WModuleFactory():
00044 m_prototypes(),
00045 m_moduleLoader()
00046 {
00047
00048 }
00049
00050 WModuleFactory::~WModuleFactory()
00051 {
00052
00053 }
00054
00055 void WModuleFactory::load()
00056 {
00057
00058 WLogger::getLogger()->addLogMessage( "Loading Modules", "ModuleFactory", LL_INFO );
00059
00060
00061 PrototypeSharedContainerType::WriteTicket m_prototypeAccess = m_prototypes.getWriteTicket();
00062
00063
00064 m_moduleLoader.load( m_prototypeAccess );
00065
00066
00067 m_prototypeAccess.reset();
00068
00069
00070 PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
00071
00072
00073 std::set< std::string > names;
00074 for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
00075 ++listIter )
00076 {
00077 WLogger::getLogger()->addLogMessage( "Initializing module prototype: \"" + ( *listIter )->getName() + "\"", "ModuleFactory", LL_DEBUG );
00078
00079
00080 if( names.count( ( *listIter )->getName() ) )
00081 {
00082 throw WPrototypeNotUnique( std::string( "Module \"" + ( *listIter )->getName()
00083 + "\" is not unique. Modules have to have a unique name." ) );
00084 }
00085 names.insert( ( *listIter )->getName() );
00086
00087 initializeModule( ( *listIter ) );
00088 }
00089 }
00090
00091 bool WModuleFactory::isPrototype( boost::shared_ptr< WModule > module )
00092 {
00093
00094 PrototypeSharedContainerType::ReadTicket l = getModuleFactory()->m_prototypes.getReadTicket();
00095 return getModuleFactory()->checkPrototype( module, l );
00096 }
00097
00098 bool WModuleFactory::checkPrototype( boost::shared_ptr< WModule > module, PrototypeSharedContainerType::ReadTicket ticket )
00099 {
00100 return ( ticket->get().count( module ) != 0 );
00101 }
00102
00103 boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule > prototype )
00104 {
00105 wlog::debug( "ModuleFactory" ) << "Creating new instance of prototype \"" << prototype->getName() << "\".";
00106
00107
00108 PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
00109
00110
00111 if( !checkPrototype( prototype, l ) )
00112 {
00113 throw WPrototypeUnknown( std::string( "Could not clone module \"" + prototype->getName() + "\" since it is no prototype." ) );
00114 }
00115
00116
00117 l.reset();
00118
00119
00120 boost::shared_ptr< WModule > clone = boost::shared_ptr< WModule >( prototype->factory() );
00121 clone->setLocalPath( prototype->getLocalPath() );
00122 initializeModule( clone );
00123
00124 return clone;
00125 }
00126
00127 void WModuleFactory::initializeModule( boost::shared_ptr< WModule > module )
00128 {
00129 module->initialize();
00130 }
00131
00132 boost::shared_ptr< WModuleFactory > WModuleFactory::getModuleFactory()
00133 {
00134 if( !m_instance )
00135 {
00136 m_instance = boost::shared_ptr< WModuleFactory >( new WModuleFactory() );
00137 }
00138
00139 return m_instance;
00140 }
00141
00142
00143 const boost::shared_ptr< WModule > WModuleFactory::isPrototypeAvailable( std::string name )
00144 {
00145
00146 PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
00147
00148
00149 boost::shared_ptr< WModule > ret = boost::shared_ptr< WModule >();
00150 for( std::set< boost::shared_ptr< WModule > >::const_iterator listIter = l->get().begin(); listIter != l->get().end();
00151 ++listIter )
00152 {
00153 if( ( *listIter )->getName() == name )
00154 {
00155 ret = ( *listIter );
00156 break;
00157 }
00158 }
00159
00160 return ret;
00161 }
00162
00163 const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByName( std::string name )
00164 {
00165 boost::shared_ptr< WModule > ret = isPrototypeAvailable( name );
00166
00167
00168 if( ret == boost::shared_ptr< WModule >() )
00169 {
00170 throw WPrototypeUnknown( std::string( "Could not find prototype \"" + name + "\"." ) );
00171 }
00172
00173 return ret;
00174 }
00175
00176 const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByInstance( boost::shared_ptr< WModule > instance )
00177 {
00178 return getPrototypeByName( instance->getName() );
00179 }
00180
00181 std::vector< WModule::ConstSPtr > WModuleFactory::getPrototypesByType( MODULE_TYPE type )
00182 {
00183 std::vector< WModule::ConstSPtr > ret;
00184
00185
00186 PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
00187
00188
00189 for( std::set< boost::shared_ptr< WModule > >::const_iterator listIter = l->get().begin(); listIter != l->get().end();
00190 ++listIter )
00191 {
00192 if( ( *listIter )->getType() == type )
00193 {
00194 ret.push_back( *listIter );
00195 }
00196 }
00197
00198 return ret;
00199 }
00200
00201 WModuleFactory::PrototypeSharedContainerType::ReadTicket WModuleFactory::getPrototypes() const
00202 {
00203 return m_prototypes.getReadTicket();
00204 }
00205
00206 WCombinerTypes::WCompatiblesList WModuleFactory::getCompatiblePrototypes( boost::shared_ptr< WModule > module )
00207 {
00208 WCombinerTypes::WCompatiblesList compatibles;
00209
00210
00211 PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
00212
00213
00214 for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
00215 ++listIter )
00216 {
00217
00218 WModule::InputConnectorList pcons = ( *listIter )->getInputConnectors();
00219 if( pcons.size() == 0 )
00220 {
00221
00222 WCombinerTypes::WOneToOneCombiners lComp;
00223
00224
00225 lComp.push_back( boost::shared_ptr< WApplyCombiner >( new WApplyCombiner( module, "", *listIter, "" ) ) );
00226
00227
00228 compatibles.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
00229 }
00230 }
00231
00232
00233 if( module )
00234 {
00235
00236 for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
00237 ++listIter )
00238 {
00239 WCombinerTypes::WOneToOneCombiners lComp = WApplyCombiner::createCombinerList< WApplyCombiner >( module, ( *listIter ) );
00240
00241
00242 if( lComp.size() != 0 )
00243 {
00244 compatibles.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
00245 }
00246 }
00247 }
00248
00249
00250 l.reset();
00251
00252
00253 std::sort( compatibles.begin(), compatibles.end(), WCombinerTypes::compatiblesSort );
00254
00255 return compatibles;
00256 }