CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/Fireworks/Core/src/FWGenericHandle.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Class  :     FWGenericHandle
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Thu Mar 30 15:48:37 EST 2006
00011 //
00012 
00013 // system include files
00014 
00015 // user include files
00016 #include "Fireworks/Core/src/FWGenericHandle.h"
00017 
00018 namespace edm {
00019 void convert_handle(BasicHandle const& orig,
00020                     Handle<FWGenericObject>& result)
00021 {
00022   if(orig.failedToGet()) {
00023     result.setWhyFailed(orig.whyFailed());
00024     return;
00025   }
00026   EDProduct const* originalWrap = orig.wrapper();
00027   if (originalWrap == 0)
00028     throw edm::Exception(edm::errors::InvalidReference,"NullPointer")
00029       << "edm::BasicHandle has null pointer to Wrapper";
00030   
00031   //Since a pointer to an EDProduct is not necessarily the same as a pointer to the actual type
00032   // (compilers are allowed to offset the two) we must get our object via a two step process
00033   Reflex::Object edproductObject(Reflex::Type::ByTypeInfo(typeid(EDProduct)), const_cast<EDProduct*>(originalWrap));
00034   assert(edproductObject != Reflex::Object());
00035   
00036   Reflex::Object wrap(edproductObject.CastObject(edproductObject.DynamicType()));
00037   assert(wrap != Reflex::Object());
00038   
00039   Reflex::Object product(wrap.Get("obj"));
00040   
00041   if(!product){
00042     throw edm::Exception(edm::errors::LogicError)<<"FWGenericObject could not find 'obj' member";
00043   }
00044   if(product.TypeOf().IsTypedef()){
00045     //For a 'Reflex::Typedef' the 'ToType' method returns the actual type
00046     // this is needed since you are now allowed to 'invoke' methods of a 'Typedef'
00047     // only for a 'real' class
00048     product = Reflex::Object(product.TypeOf().ToType(), product.Address());
00049     assert(!product.TypeOf().IsTypedef());
00050   }
00051   // NOTE: comparing on type doesn't seem to always work! The problem appears to be if we have a typedef
00052   if(product.TypeOf()!=result.type() &&
00053      !product.TypeOf().IsEquivalentTo(result.type()) &&
00054      product.TypeOf().TypeInfo()!= result.type().TypeInfo()){
00055         std::cerr << "FWGenericObject asked for "<<result.type().Name()
00056          <<" but was given a " << product.TypeOf().Name();
00057     throw edm::Exception(edm::errors::LogicError)<<"FWGenericObject asked for "<<result.type().Name()
00058     <<" but was given a "<<product.TypeOf().Name();
00059   }
00060   
00061   Handle<FWGenericObject> h(product, orig.provenance(), orig.id());
00062   h.swap(result);
00063 }
00064 
00066 template<>
00067 bool
00068 edm::EventBase::getByLabel<FWGenericObject>(edm::InputTag const& tag,
00069                                              Handle<FWGenericObject>& result) const
00070 {
00071    std::string dataTypeName = result.type().Name(ROOT::Reflex::SCOPED);
00072    if (dataTypeName[dataTypeName.size() -1] == '>')
00073       dataTypeName += " ";
00074    std::string wrapperName = "edm::Wrapper<" + dataTypeName + ">";
00075 
00076    ROOT::Reflex::Type wrapperType = ROOT::Reflex::Type::ByName(wrapperName);
00077 
00078    BasicHandle bh = this->getByLabelImpl(wrapperType.TypeInfo(),
00079                                          result.type().TypeInfo(),
00080                                          tag);
00081    convert_handle(bh, result);  // throws on conversion error
00082    if(bh.failedToGet()) 
00083       return false;
00084    return true;
00085 }
00086 
00087 }