Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

#include "FWCore/Framework/interface/maker/ModuleMaker.h"
#include "FWCore/Framework/interface/SignallingProductRegistryFiller.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/Registry.h"
#include "DataFormats/Provenance/interface/ModuleDescription.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/Utilities/interface/ConvertException.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/Utilities/interface/EDMException.h"
#include "FWCore/Utilities/interface/thread_safety_macros.h"

#include <sstream>
#include <exception>
namespace edm {

  ModuleMakerBase::~ModuleMakerBase() {}

  ModuleDescription ModuleMakerBase::createModuleDescription(MakeModuleParams const& p) const {
    ParameterSet const& conf = *p.pset_;
    ModuleDescription md(conf.id(),
                         conf.getParameter<std::string>("@module_type"),
                         conf.getParameter<std::string>("@module_label"),
                         p.processConfiguration_.get(),
                         ModuleDescription::getUniqueID());
    return md;
  }

  void ModuleMakerBase::throwValidationException(MakeModuleParams const& p, cms::Exception& iException) const {
    ParameterSet const& conf = *p.pset_;
    std::string moduleName = conf.getParameter<std::string>("@module_type");
    std::string moduleLabel = conf.getParameter<std::string>("@module_label");

    std::ostringstream ost;
    ost << "Validating configuration of module: class=" << moduleName << " label='" << moduleLabel << "'";
    iException.addContext(ost.str());
    throw;
  }

  void ModuleMakerBase::throwConfigurationException(ModuleDescription const& md, cms::Exception& iException) const {
    std::ostringstream ost;
    ost << "Constructing module: class=" << md.moduleName() << " label='" << md.moduleLabel() << "'";
    iException.addContext(ost.str());
    throw;
  }

  void ModuleMakerBase::validateEDMType(std::string const& edmType, MakeModuleParams const& p) const {
    std::string expected = p.pset_->getParameter<std::string>("@module_edm_type");
    if (edmType != expected) {
      throw Exception(errors::Configuration)
          << "The base type in the python configuration is " << expected << ", but the base type\n"
          << "for the module's C++ class is " << edmType << ". "
          << "Please fix the configuration.\n"
          << "It must use the same base type as the C++ class.\n";
    }
  }

  std::shared_ptr<maker::ModuleHolder> ModuleMakerBase::makeModule(
      MakeModuleParams const& p,
      signalslot::Signal<void(ModuleDescription const&)>& pre,
      signalslot::Signal<void(ModuleDescription const&)>& post) const {
    // Add process_name for SwitchProducer
    if (p.pset_->getParameter<std::string>("@module_type") == "SwitchProducer") {
      p.pset_->addUntrackedParameter("@process_name", p.processConfiguration_->processName());
    }

    ConfigurationDescriptions descriptions(baseType(), p.pset_->getParameter<std::string>("@module_type"));
    fillDescriptions(descriptions);
    try {
      convertException::wrap([&]() {
        descriptions.validate(*p.pset_, p.pset_->getParameter<std::string>("@module_label"));
        validateEDMType(baseType(), p);
      });
    } catch (cms::Exception& iException) {
      throwValidationException(p, iException);
    }
    p.pset_->registerIt();
    //Need to be certain top level untracked parameters are stored in
    // the registry even if another PSet already exists in the
    // registry from a previous process
    //NOTE: a better implementation would be to change ParameterSet::registerIt
    // but that would require rebuilding much more code so will be done at
    // a later date.
    edm::pset::Registry::instance()->insertMapped(*(p.pset_), true);

    ModuleDescription md = createModuleDescription(p);
    std::shared_ptr<maker::ModuleHolder> module;
    bool postCalled = false;
    try {
      convertException::wrap([&]() {
        pre(md);
        module = makeModule(*(p.pset_));
        module->finishModuleInitialization(md, *p.preallocate_, p.reg_);
        // if exception then post will be called in the catch block
        postCalled = true;
        post(md);
      });
    } catch (cms::Exception& iException) {
      if (!postCalled) {
        CMS_SA_ALLOW try { post(md); } catch (...) {
          // If post throws an exception ignore it because we are already handling another exception
        }
      }
      throwConfigurationException(md, iException);
    }
    return module;
  }
}  // namespace edm