Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:01

0001 #ifndef Framework_ComponentMaker_h
0002 #define Framework_ComponentMaker_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     Framework
0006 // Class  :     ComponentMaker
0007 //
0008 /**\class ComponentMaker ComponentMaker.h FWCore/Framework/interface/ComponentMaker.h
0009 
0010  Description: <one line class summary>
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Author:      Chris Jones
0018 // Created:     Wed May 25 16:56:05 EDT 2005
0019 //
0020 
0021 // system include files
0022 #include <memory>
0023 #include <string>
0024 
0025 #include <fmt/format.h>
0026 
0027 // user include files
0028 #include "FWCore/Framework/interface/ComponentDescription.h"
0029 #include "FWCore/Framework/interface/ESProductResolverProvider.h"
0030 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0031 #include "FWCore/ParameterSet/interface/ParameterSetDescriptionFiller.h"
0032 #include "FWCore/Utilities/interface/ConvertException.h"
0033 
0034 // forward declarations
0035 
0036 namespace edm {
0037   namespace eventsetup {
0038     class EventSetupProvider;
0039     class EventSetupsController;
0040     class ESProductResolverProvider;
0041 
0042     class ComponentMakerBaseHelper {
0043     public:
0044       virtual ~ComponentMakerBaseHelper() {}
0045 
0046     protected:
0047       ComponentDescription createComponentDescription(ParameterSet const& iConfiguration) const;
0048     };
0049 
0050     template <class T>
0051     class ComponentMakerBase : public ComponentMakerBaseHelper {
0052     public:
0053       typedef typename T::base_type base_type;
0054       virtual std::shared_ptr<base_type> addTo(EventSetupsController& esController,
0055                                                EventSetupProvider& iProvider,
0056                                                ParameterSet& iConfiguration,
0057                                                bool replaceExisting) const = 0;
0058     };
0059 
0060     template <class T, class TComponent>
0061     class ComponentMaker : public ComponentMakerBase<T> {
0062     public:
0063       ComponentMaker() {}
0064       ComponentMaker(const ComponentMaker&) = delete;                   // stop default
0065       const ComponentMaker& operator=(const ComponentMaker&) = delete;  // stop default
0066       typedef typename T::base_type base_type;
0067 
0068       // ---------- const member functions ---------------------
0069       std::shared_ptr<base_type> addTo(EventSetupsController& esController,
0070                                        EventSetupProvider& iProvider,
0071                                        ParameterSet& iConfiguration,
0072                                        bool replaceExisting) const override;
0073 
0074       // ---------- static member functions --------------------
0075 
0076       // ---------- member functions ---------------------------
0077     private:
0078       void setDescription(ESProductResolverProvider* iProv, const ComponentDescription& iDesc) const {
0079         iProv->setDescription(iDesc);
0080       }
0081       void setDescriptionForFinder(EventSetupRecordIntervalFinder* iFinder, const ComponentDescription& iDesc) const {
0082         iFinder->setDescriptionForFinder(iDesc);
0083       }
0084       void setPostConstruction(ESProductResolverProvider* iProv, const edm::ParameterSet& iPSet) const {
0085         //The 'appendToDataLabel' parameter was added very late in the development cycle and since
0086         // the ParameterSet is not sent to the base class we must set the value after construction
0087         iProv->setAppendToDataLabel(iPSet);
0088       }
0089       void setDescription(void*, const ComponentDescription&) const {}
0090       void setDescriptionForFinder(void*, const ComponentDescription&) const {}
0091       void setPostConstruction(void*, const edm::ParameterSet&) const {}
0092       // ---------- member data --------------------------------
0093     };
0094 
0095     template <class T, class TComponent>
0096     std::shared_ptr<typename ComponentMaker<T, TComponent>::base_type> ComponentMaker<T, TComponent>::addTo(
0097         EventSetupsController& esController,
0098         EventSetupProvider& iProvider,
0099         ParameterSet& iConfiguration,
0100         bool replaceExisting) const {
0101       // This adds components to the EventSetupProvider for the process. It might
0102       // make a new component then add it or reuse a component from an earlier
0103       // SubProcess or the top level process and add that.
0104 
0105       {
0106         auto modtype = iConfiguration.getParameter<std::string>("@module_type");
0107         auto moduleLabel = iConfiguration.getParameter<std::string>("@module_label");
0108         try {
0109           edm::convertException::wrap([&]() {
0110             ConfigurationDescriptions descriptions(T::baseType(), modtype);
0111             fillDetails::fillIfExists<TComponent>(descriptions);
0112             fillDetails::prevalidateIfExists<TComponent>(descriptions);
0113             descriptions.validate(iConfiguration, moduleLabel);
0114             iConfiguration.registerIt();
0115           });
0116         } catch (cms::Exception& iException) {
0117           iException.addContext(fmt::format(
0118               "Validating configuration of {} of type {} with label: '{}'", T::baseType(), modtype, moduleLabel));
0119           throw;
0120         }
0121       }
0122 
0123       if (!replaceExisting) {
0124         std::shared_ptr<typename T::base_type> alreadyMadeComponent =
0125             T::getComponentAndRegisterProcess(esController, iConfiguration);
0126 
0127         if (alreadyMadeComponent) {
0128           // This is for the case when a component is shared between
0129           // a SubProcess and a previous SubProcess or the top level process
0130           // because the component has an identical configuration to a component
0131           // from the top level process or earlier SubProcess.
0132           std::shared_ptr<TComponent> component(
0133               std::static_pointer_cast<TComponent, typename T::base_type>(alreadyMadeComponent));
0134           T::addTo(iProvider, component, iConfiguration, true);
0135           return component;
0136         }
0137       }
0138 
0139       std::shared_ptr<TComponent> component = std::make_shared<TComponent>(iConfiguration);
0140       ComponentDescription description = this->createComponentDescription(iConfiguration);
0141 
0142       this->setDescription(component.get(), description);
0143       this->setDescriptionForFinder(component.get(), description);
0144       this->setPostConstruction(component.get(), iConfiguration);
0145 
0146       if (replaceExisting) {
0147         // This case is for ESProducers where in the first pass
0148         // the algorithm thought the component could be shared
0149         // across SubProcess's because there was an ESProducer
0150         // from a previous process with an identical configuration.
0151         // But in a later check it was determined that sharing was not
0152         // possible because other components associated with the
0153         // same record or records that record depends on had
0154         // differing configurations.
0155         T::replaceExisting(iProvider, component);
0156       } else {
0157         // This is for the case when a new component is being constructed.
0158         // All components for the top level process fall in this category.
0159         // Or it could be a SubProcess where neither the top level process
0160         // nor any prior SubProcess had a component with exactly the same configuration.
0161         T::addTo(iProvider, component, iConfiguration, false);
0162         T::putComponent(esController, iConfiguration, component);
0163       }
0164       return component;
0165     }
0166   }  // namespace eventsetup
0167 }  // namespace edm
0168 #endif