Go to the documentation of this file.00001 #ifndef Framework_ComponentFactory_h
00002 #define Framework_ComponentFactory_h
00003
00004
00005
00006
00007
00016
00017
00018
00019
00020
00021
00022 #include <string>
00023 #include <map>
00024 #include <exception>
00025 #include "boost/shared_ptr.hpp"
00026
00027
00028 #include "FWCore/PluginManager/interface/PluginFactory.h"
00029 #include "DataFormats/Provenance/interface/PassID.h"
00030 #include "DataFormats/Provenance/interface/ReleaseVersion.h"
00031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00032 #include "FWCore/Framework/interface/ComponentMaker.h"
00033 #include "FWCore/Utilities/interface/ConvertException.h"
00034 #include "FWCore/Utilities/interface/EDMException.h"
00035 #include "FWCore/Utilities/interface/Exception.h"
00036
00037
00038 namespace edm {
00039 namespace eventsetup {
00040 class EventSetupProvider;
00041
00042 template<typename T>
00043 class ComponentFactory
00044 {
00045
00046 public:
00047 ComponentFactory(): makers_() {}
00048
00049
00050 typedef ComponentMakerBase<T> Maker;
00051 typedef std::map<std::string, boost::shared_ptr<Maker> > MakerMap;
00052 typedef typename T::base_type base_type;
00053
00054 boost::shared_ptr<base_type> addTo(EventSetupProvider& iProvider,
00055 edm::ParameterSet const& iConfiguration,
00056 std::string const& iProcessName,
00057 ReleaseVersion const& iVersion,
00058 PassID const& iPass) const
00059 {
00060 std::string modtype = iConfiguration.template getParameter<std::string>("@module_type");
00061
00062 typename MakerMap::iterator it = makers_.find(modtype);
00063
00064 if(it == makers_.end())
00065 {
00066 boost::shared_ptr<Maker> wm(edmplugin::PluginFactory<ComponentMakerBase<T>* ()>::get()->create(modtype));
00067
00068 if(wm.get() == 0) {
00069 Exception::throwThis(errors::Configuration,
00070 "UnknownModule",
00071 T::name().c_str(),
00072 " of type ",
00073 modtype.c_str(),
00074 " has not been registered.\n"
00075 "Perhaps your module type is misspelled or is not a "
00076 "framework plugin.\n"
00077 "Try running EdmPluginDump to obtain a list of "
00078 "available Plugins.");
00079 }
00080
00081
00082
00083 std::pair<typename MakerMap::iterator,bool> ret =
00084 makers_.insert(std::pair<std::string,boost::shared_ptr<Maker> >(modtype,wm));
00085
00086 if(ret.second == false) {
00087 Exception::throwThis(errors::Configuration,"Maker Factory map insert failed");
00088 }
00089
00090 it = ret.first;
00091 }
00092
00093 try {
00094 try {
00095 return it->second->addTo(iProvider,iConfiguration,iProcessName,iVersion,iPass);
00096 }
00097 catch (cms::Exception& e) { throw; }
00098 catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
00099 catch (std::exception& e) { convertException::stdToEDM(e); }
00100 catch(std::string& s) { convertException::stringToEDM(s); }
00101 catch(char const* c) { convertException::charPtrToEDM(c); }
00102 catch (...) { convertException::unknownToEDM(); }
00103 }
00104 catch(cms::Exception & iException) {
00105 std::string edmtype = iConfiguration.template getParameter<std::string>("@module_edm_type");
00106 std::string label = iConfiguration.template getParameter<std::string>("@module_label");
00107 std::ostringstream ost;
00108 ost << "Constructing " << edmtype << ": class=" << modtype << " label='" << label << "'";
00109 iException.addContext(ost.str());
00110 throw;
00111 }
00112 return boost::shared_ptr<base_type>();
00113 }
00114
00115
00116 static ComponentFactory<T>* get();
00117
00118
00119
00120 private:
00121
00122 ComponentFactory(const ComponentFactory&);
00123
00124 const ComponentFactory& operator=(const ComponentFactory&);
00125
00126
00127 mutable MakerMap makers_;
00128 };
00129
00130 }
00131 }
00132 #define COMPONENTFACTORY_GET(_type_) \
00133 EDM_REGISTER_PLUGINFACTORY(edmplugin::PluginFactory<edm::eventsetup::ComponentMakerBase<_type_>* ()>,_type_::name()); \
00134 static edm::eventsetup::ComponentFactory<_type_> s_dummyfactory; \
00135 namespace edm { namespace eventsetup { \
00136 template<> edm::eventsetup::ComponentFactory<_type_>* edm::eventsetup::ComponentFactory<_type_>::get() \
00137 { return &s_dummyfactory; } \
00138 } } \
00139 typedef int componentfactory_get_needs_semicolon
00140
00141 #endif