openModeller  Version 1.4.0
PreFactory.hh
Go to the documentation of this file.
00001 
00026 #ifndef  PRE_FACTORY_HH
00027 #define  PRE_FACTORY_HH
00028 
00029 #include <map>
00030 #include <string>
00031 
00032 using namespace std;
00033 
00034 //adapted from Terralib to OM Pre-analysis ( Missae DPI/INPE )
00035 
00050 template <class T, class Arg>
00051 class PreFactory
00052 {
00053 public:
00054 
00055     // Dictionary of factories (indexed by name)
00056   typedef map<string, PreFactory<T,Arg>* > PreFactoryMap; 
00057 
00058     // Returns the single instance of the factory dictionay
00059   static PreFactoryMap& instance ()
00060   { 
00061     static PreFactoryMap Fmap_;
00062     return Fmap_;
00063     
00064   } 
00065   
00066   // Normal Constructor
00067   PreFactory (const string& factoryName);
00068 
00069   virtual ~PreFactory() {}
00070 
00071   // Virtual constructor using name
00072   static T* make  ( string name, const Arg& arg );
00073 
00074 protected:
00075 
00076   // Builds a new type (should be implemented by descendants)
00077     virtual T* build ( const Arg& arg ) = 0;
00078 
00079 private:
00080   string  Fname_;
00081 };
00082 
00083 // Constructor 
00084 template <class T, class Arg>
00085 PreFactory<T,Arg>::PreFactory(const string& name):
00086   Fname_(name)
00087 {
00088   PreFactory<T,Arg>::instance()[name] = this;
00089 }
00090   
00091 // Builds an object, based on the input parameters
00092 template <class T, class Arg> 
00093 T*
00094 PreFactory<T,Arg>::make ( string name, const Arg& arg )
00095 {
00096   // try to find the name on the factory dictionary
00097   typename PreFactoryMap::iterator i = PreFactory<T,Arg>::instance().find ( name );
00098 
00099   // Not found ?  
00100   if ( i == PreFactory<T,Arg>::instance().end() )
00101   {
00102     std::string msg = "PreFactory<T,Arg>::make( string name, const Arg& arg ): Not found the name on the factory\n";
00103     Log::instance()->error( msg.c_str() );
00104     throw InvalidParameterException( msg );
00105   }
00106 
00107   // Create an object, based on the input parameters
00108   return (*i).second->build ( arg );
00109   return 0;
00110 
00111 } 
00112 
00113 #endif
00114