00001
00002
00003
00004 #include <algorithm>
00005
00006 #include "FWCore/Framework/interface/PrincipalGetAdapter.h"
00007 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00008 #include "FWCore/Framework/interface/Principal.h"
00009 #include "FWCore/Utilities/interface/EDMException.h"
00010 #include "FWCore/Utilities/interface/ProductKindOfType.h"
00011 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00012 #include "DataFormats/Provenance/interface/ProductHolderIndexHelper.h"
00013 #include "FWCore/Framework/interface/EDConsumerBase.h"
00014
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016
00017 namespace edm {
00018
00019 PrincipalGetAdapter::PrincipalGetAdapter(Principal & pcpl,
00020 ModuleDescription const& md) :
00021
00022 principal_(pcpl),
00023 md_(md) {
00024 }
00025
00026 PrincipalGetAdapter::~PrincipalGetAdapter() {
00027 }
00028
00029
00030 void
00031 principal_get_adapter_detail::deleter::operator()(std::pair<WrapperOwningHolder, ConstBranchDescription const*> const p) const {
00032 WrapperOwningHolder* edp = const_cast<WrapperOwningHolder*>(&p.first);
00033 edp->reset();
00034 }
00035
00036 void
00037 principal_get_adapter_detail::throwOnPutOfNullProduct(
00038 char const* principalType,
00039 TypeID const& productType,
00040 std::string const& productInstanceName) {
00041 throw Exception(errors::NullPointerError)
00042 << principalType
00043 << "::put: A null auto_ptr was passed to 'put'.\n"
00044 << "The pointer is of type "
00045 << productType
00046 << ".\nThe specified productInstanceName was '"
00047 << productInstanceName
00048 << "'.\n";
00049 }
00050
00051 void
00052 principal_get_adapter_detail::throwOnPrematureRead(
00053 char const* principalType,
00054 TypeID const& productType,
00055 std::string const& moduleLabel,
00056 std::string const& productInstanceName) {
00057
00058 LogWarning("LogicError")
00059 << "::getByLabel: An attempt was made to read a "
00060 << principalType
00061 << " product before end"
00062 << principalType
00063 << "() was called.\n"
00064 << "The product is of type '"
00065 << productType
00066 << "'.\nThe specified ModuleLabel was '"
00067 << moduleLabel
00068 << "'.\nThe specified productInstanceName was '"
00069 << productInstanceName
00070 << "'.\n";
00071 }
00072
00073 void
00074 principal_get_adapter_detail::throwOnPrematureRead(
00075 char const* principalType,
00076 TypeID const& productType) {
00077
00078 LogWarning("LogicError")
00079 << "::getManyByType: An attempt was made to read a "
00080 << principalType
00081 << " product before end"
00082 << principalType
00083 << "() was called.\n"
00084 << "The product is of type '"
00085 << productType
00086 << "'.\n";
00087 }
00088
00089 void
00090 principal_get_adapter_detail::throwOnPrematureRead(
00091 char const* principalType,
00092 TypeID const& productType,
00093 EDGetToken token) {
00094 throw Exception(errors::LogicError)
00095 << "::getByToken: An attempt was made to read a "
00096 << principalType
00097 << " product before end"
00098 << principalType
00099 << "() was called.\n"
00100 << "The index of the token was "<<token.index()<<".\n";
00101 }
00102
00103 BasicHandle
00104 PrincipalGetAdapter::makeFailToGetException(KindOfType kindOfType,
00105 TypeID const& productType,
00106 EDGetToken token) const {
00107 EDConsumerBase::Labels labels;
00108 consumer_->labelsForToken(token,labels);
00109 boost::shared_ptr<cms::Exception> exception(new Exception(errors::ProductNotFound));
00110 if (kindOfType == PRODUCT_TYPE) {
00111 *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for type: " << productType << "\n"
00112 << "Looking for module label: " << labels.module << "\n" << "Looking for productInstanceName: " << labels.productInstance << "\n"
00113 << (0==labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n";
00114 } else {
00115 *exception << "Principal::getByToken: Found zero products matching all criteria\nLooking for a container with elements of type: " << productType << "\n"
00116 << "Looking for module label: " << labels.module << "\n" << "Looking for productInstanceName: " << labels.productInstance << "\n"
00117 << (0==labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n";
00118 }
00119 return BasicHandle(exception);
00120 }
00121
00122 void
00123 PrincipalGetAdapter::throwAmbiguousException(TypeID const& productType,
00124 EDGetToken token) const {
00125 EDConsumerBase::Labels labels;
00126 consumer_->labelsForToken(token,labels);
00127 cms::Exception exception("AmbiguousProduct");
00128 exception << "Principal::getByToken: More than 1 product matches all criteria\nLooking for a container with elements of type: " << productType << "\n"
00129 << "Looking for module label: " << labels.module << "\n" << "Looking for productInstanceName: " << labels.productInstance << "\n"
00130 << (0==labels.process[0] ? "" : "Looking for process: ") << labels.process << "\n"
00131 << "This can only occur with get function calls using a Handle<View> argument.\n"
00132 << "Try a get not using a View or change the instance name of one of the products";
00133 throw exception;
00134 }
00135
00136 BranchType const&
00137 PrincipalGetAdapter::branchType() const {
00138 return principal_.branchType();
00139 }
00140
00141 BasicHandle
00142 PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
00143 InputTag const& tag) const {
00144 return principal_.getByLabel(PRODUCT_TYPE, typeID, tag);
00145 }
00146
00147 BasicHandle
00148 PrincipalGetAdapter::getByLabel_(TypeID const& typeID,
00149 std::string const& label,
00150 std::string const& instance,
00151 std::string const& process) const {
00152 return principal_.getByLabel(PRODUCT_TYPE, typeID, label, instance, process);
00153 }
00154
00155 BasicHandle
00156 PrincipalGetAdapter::getByToken_(TypeID const& id, KindOfType kindOfType, EDGetToken token) const {
00157 ProductHolderIndex index = consumer_->indexFrom(token,InEvent,id);
00158 if( unlikely(index == ProductHolderIndexInvalid)) {
00159 return makeFailToGetException(kindOfType,id,token);
00160 } else if( unlikely(index == ProductHolderIndexAmbiguous)) {
00161
00162 throwAmbiguousException(id, token);
00163 }
00164 bool ambiguous = false;
00165 BasicHandle h = principal_.getByToken(kindOfType,id,index, token.willSkipCurrentProcess(), ambiguous);
00166 if (ambiguous) {
00167
00168 throwAmbiguousException(id, token);
00169 } else if(!h.isValid()) {
00170 return makeFailToGetException(kindOfType,id,token);
00171 }
00172 return h;
00173 }
00174
00175 BasicHandle
00176 PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
00177 InputTag const& tag) const {
00178 return principal_.getByLabel(ELEMENT_TYPE, typeID, tag);
00179 }
00180
00181 BasicHandle
00182 PrincipalGetAdapter::getMatchingSequenceByLabel_(TypeID const& typeID,
00183 std::string const& label,
00184 std::string const& instance,
00185 std::string const& process) const {
00186 return principal_.getByLabel(ELEMENT_TYPE,
00187 typeID,
00188 label,
00189 instance,
00190 process);
00191 }
00192
00193 void
00194 PrincipalGetAdapter::getManyByType_(TypeID const& tid,
00195 BasicHandleVec& results) const {
00196 principal_.getManyByType(tid, results);
00197 }
00198
00199 ProcessHistory const&
00200 PrincipalGetAdapter::processHistory() const {
00201 return principal_.processHistory();
00202 }
00203
00204 ConstBranchDescription const&
00205 PrincipalGetAdapter::getBranchDescription(TypeID const& type,
00206 std::string const& productInstanceName) const {
00207 ProductHolderIndexHelper const& productHolderIndexHelper = principal_.productLookup();
00208 ProductHolderIndex index = productHolderIndexHelper.index(PRODUCT_TYPE, type, md_.moduleLabel().c_str(),productInstanceName.c_str(), md_.processName().c_str());
00209 if(index == ProductHolderIndexInvalid) {
00210 throw edm::Exception(edm::errors::InsertFailure)
00211 << "Illegal attempt to 'put' an unregistered product.\n"
00212 << "No product is registered for\n"
00213 << " process name: '" << md_.processName() << "'\n"
00214 << " module label: '" << md_.moduleLabel() << "'\n"
00215 << " product friendly class name: '" << type.friendlyClassName() << "'\n"
00216 << " product instance name: '" << productInstanceName << "'\n"
00217
00218 << "The ProductRegistry contains:\n"
00219 << principal_.productRegistry()
00220 << '\n';
00221 }
00222 ProductHolderBase const* phb = principal_.getProductByIndex(index, false, false);
00223 assert(phb != nullptr);
00224 return phb->branchDescription();
00225 }
00226
00227 EDProductGetter const*
00228 PrincipalGetAdapter::prodGetter() const{
00229 return principal_.prodGetter();
00230 }
00231
00232 bool
00233 PrincipalGetAdapter::isComplete() const {
00234 return principal_.isComplete();
00235 }
00236 }