CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/Fireworks/Core/src/FWItemAccessorFactory.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWItemAccessorFactory
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Sat Oct 18 14:48:14 EDT 2008
00011 // $Id: FWItemAccessorFactory.cc,v 1.11 2010/09/13 13:49:29 matevz Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include "TClass.h"
00017 #include "TVirtualCollectionProxy.h"
00018 #include "Reflex/Type.h"
00019 #include "Reflex/Member.h"
00020 
00021 // user include files
00022 #include "Fireworks/Core/interface/FWItemAccessorFactory.h"
00023 #include "Fireworks/Core/interface/FWItemAccessorRegistry.h"
00024 #include "Fireworks/Core/src/FWItemTVirtualCollectionProxyAccessor.h"
00025 #include "Fireworks/Core/src/FWItemSingleAccessor.h"
00026 #include "Fireworks/Core/interface/fwLog.h"
00027 
00028 //
00029 // constants, enums and typedefs
00030 //
00031 
00032 //
00033 // static data member definitions
00034 //
00035 
00036 //
00037 // constructors and destructor
00038 //
00039 FWItemAccessorFactory::FWItemAccessorFactory()
00040 {
00041 }
00042 
00043 // FWItemAccessorFactory::FWItemAccessorFactory(const FWItemAccessorFactory& rhs)
00044 // {
00045 //    // do actual copying here;
00046 // }
00047 
00048 FWItemAccessorFactory::~FWItemAccessorFactory()
00049 {
00050 }
00051 
00052 //
00053 // assignment operators
00054 //
00055 // const FWItemAccessorFactory& FWItemAccessorFactory::operator=(const FWItemAccessorFactory& rhs)
00056 // {
00057 //   //An exception safe implementation is
00058 //   FWItemAccessorFactory temp(rhs);
00059 //   swap(rhs);
00060 //
00061 //   return *this;
00062 // }
00063 
00064 //
00065 // member functions
00066 //
00067 
00068 //
00069 // const member functions
00070 //
00071 
00094 boost::shared_ptr<FWItemAccessorBase>
00095 FWItemAccessorFactory::accessorFor(const TClass* iClass) const
00096 {
00097    static const bool debug = false;
00098 
00099    TClass *member = 0;
00100    size_t offset=0;
00101 
00102    if(hasTVirtualCollectionProxy(iClass)) 
00103    {
00104       if (debug)
00105          fwLog(fwlog::kDebug) << "class " << iClass->GetName()
00106                               << " uses FWItemTVirtualCollectionProxyAccessor." << std::endl;
00107       return boost::shared_ptr<FWItemAccessorBase>(
00108          new FWItemTVirtualCollectionProxyAccessor(iClass,
00109             boost::shared_ptr<TVirtualCollectionProxy>(iClass->GetCollectionProxy()->Generate())));
00110    } 
00111    else if (hasMemberTVirtualCollectionProxy(iClass, member,offset)) 
00112    {
00113       if (debug)
00114          fwLog(fwlog::kDebug) << "class "<< iClass->GetName()
00115                               << " only contains data member " << member->GetName()
00116                               << " which uses FWItemTVirtualCollectionProxyAccessor."
00117                               << std::endl;
00118            
00119       return boost::shared_ptr<FWItemAccessorBase>(
00120          new FWItemTVirtualCollectionProxyAccessor(iClass,
00121             boost::shared_ptr<TVirtualCollectionProxy>(member->GetCollectionProxy()->Generate()),
00122                                                    offset));
00123    }
00124    
00125    // Iterate on the available plugins and use the one which handles 
00126    // the iClass type. 
00127    // NOTE: This is done only a few times, not really performance critical.
00128    // If you want this to be fast, the loop can be moved in the 
00129    // constructor. Notice that this will require constructing FWEventItemsManager 
00130    // after the plugin manager (i.e. invoking AutoLibraryLoader::enable()) is configured
00131    // (i.e. invoking AutoLibraryLoader::enable()) in CmsShowMain.
00132    std::string accessorName;
00133    if (hasAccessor(iClass, accessorName))
00134    {
00135       if (debug)
00136          fwLog(fwlog::kDebug) << "class " << iClass->GetName() << " uses " 
00137                               << accessorName << "." << std::endl;
00138       return boost::shared_ptr<FWItemAccessorBase>(FWItemAccessorRegistry::get()->create(accessorName, iClass));
00139    }
00140    
00141    return boost::shared_ptr<FWItemAccessorBase>(new FWItemSingleAccessor(iClass));
00142 }
00143 
00147 bool
00148 FWItemAccessorFactory::hasTVirtualCollectionProxy(const TClass *iClass)
00149 {
00150    // Check if this is a collection known by ROOT but also that the item held by
00151    // the colletion actually has a dictionary  
00152    return iClass &&
00153           iClass->GetCollectionProxy() && 
00154           iClass->GetCollectionProxy()->GetValueClass() &&
00155           iClass->GetCollectionProxy()->GetValueClass()->IsLoaded();
00156 }
00157 
00169 bool
00170 FWItemAccessorFactory::hasMemberTVirtualCollectionProxy(const TClass *iClass,
00171                                                         TClass *&oMember,
00172                                                         size_t& oOffset)
00173 {
00174    assert(iClass->GetTypeInfo());
00175    ROOT::Reflex::Type dataType(ROOT::Reflex::Type::ByTypeInfo(*(iClass->GetTypeInfo())));
00176    assert(dataType != ROOT::Reflex::Type());
00177 
00178    // If the object has more than one data member, we avoid guessing. 
00179    if (dataType.DataMemberSize() != 1)
00180       return false;
00181    
00182    ROOT::Reflex::Type memType(dataType.DataMemberAt(0).TypeOf());
00183    assert(memType != ROOT::Reflex::Type());
00184    //make sure this is the real type and not a typedef
00185    memType = memType.FinalType();
00186    oMember = TClass::GetClass(memType.TypeInfo());
00187    oOffset = dataType.DataMemberAt(0).Offset();
00188    
00189    // Check if this is a collection known by ROOT but also that the item held by
00190    // the colletion actually has a dictionary  
00191             
00192    if (!hasTVirtualCollectionProxy(oMember))
00193       return false;
00194 
00195    return true;
00196 }
00197 
00205 bool
00206 FWItemAccessorFactory::hasAccessor(const TClass *iClass, std::string &result)
00207 {
00208    const std::vector<edmplugin::PluginInfo> &available 
00209       = FWItemAccessorRegistry::get()->available();
00210    
00211    for (size_t i = 0, e = available.size(); i != e; ++i)
00212    {
00213       std::string name = available[i].name_;
00214       std::string type = name.substr(0, name.find_first_of('@'));
00215       if (iClass->GetTypeInfo()->name() == type)
00216       {
00217          result.swap(name);
00218          return true;
00219       }
00220    }
00221    return false; 
00222 }
00223 
00229 bool FWItemAccessorFactory::classAccessedAsCollection(const TClass* iClass)
00230 {
00231    std::string accessorName;
00232    TClass *member = 0;
00233    size_t offset=0;
00234    
00235    // This is pretty much the same thing that happens 
00236    return (FWItemAccessorFactory::hasTVirtualCollectionProxy(iClass) 
00237            || FWItemAccessorFactory::hasMemberTVirtualCollectionProxy(iClass, member,offset)
00238            || FWItemAccessorFactory::hasAccessor(iClass, accessorName));
00239 }
00240 
00241 //
00242 // static member functions
00243 //