Commits

Anonymous committed c2f5207

first import

Comments (0)

Files changed (14)

+package SGComps
+
+author Paolo Calafiura   <Paolo.Calafiura@cern.ch>
+
+use AtlasPolicy    AtlasPolicy-01-*
+
+use GaudiInterface GaudiInterface-* External
+
+use AthenaKernel   AthenaKernel-*   Control
+use SGTools        SGTools-*        Control
+
+library SGComps *.cxx -s=components *.cxx
+apply_pattern component_library
+
+private
+use TestTools      TestTools-*      AtlasTest              -no_auto_imports
+use ToyConversion ToyConversion-*   Control/AthenaExamples -no_auto_imports
+use StoreGate      StoreGate-*      Control                -no_auto_imports
+apply_pattern UnitTest_run unit_test=ProxyProviderSvc
+macro_append ProxyProviderSvc_testlinkopts " -L../$(CMTCONFIG) -lSGComps
+
+apply_pattern UnitTest_run unit_test=SGFolder
+

share/ProxyProviderSvc_test.ref

Binary file added.

share/ProxyProviderSvc_test.txt

+// job opts for ProxyProviderSvc unit test
+
+// $Id: ProxyProviderSvc_test.txt,v 1.1.1.1 2007-06-22 23:21:47 calaf Exp $
+
+#include "StoreGate/StoreGateTestCommon.txt"
+#include "ToyConversion/ToyConversionOpts.txt"
+ProxyProviderSvc.OutputLevel = 1;

share/SGFolder_test.ref

+*** SG::Folder_test starts ***
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/SGFolder_test.txt
+JobOptionsSvc        INFO 
+//GP:================================================================================
+//GP: include ../share/SGFolder_test.txt                                      (0,0)
+MessageSvc.OutputLevel = 2;                                             //GP: (5,1)
+ToolSvc.MyFolder.ItemList =  [ "Foo#Bla" , "Bar#*" , "8101" , "8107#" , "Baricco#*" ] ;//GP: (6,1)
+//GP: end  ../share/SGFolder_test.txt                                         (7,1)
+//GP:================================================================================
+
+JobOptionsSvc        INFO Job options successfully read in from ../share/SGFolder_test.txt
+ApplicationMgr      DEBUG Getting my own properties
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr $Revision: 1.1.1.1 $
+                                          running on lxplus203.cern.ch on Fri Jun  1 00:43:16 2007
+====================================================================================================================================
+ApplicationMgr       INFO Successfully loaded modules : 
+ApplicationMgr       INFO Application Manager Configured successfully
+ServiceManager      DEBUG Initializing service AppMgrRunable
+AppMgrRunable       DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service EventLoopMgr
+EventLoopMgr        DEBUG Service base class initialized successfully
+EventDataSvc        DEBUG Service base class initialized successfully
+IncidentSvc         DEBUG Service base class initialized successfully
+EventPersistenc...  DEBUG Service base class initialized successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramDataSvc    DEBUG Service base class initialized successfully
+HistogramPersis...   INFO  'CnvServices':[ 'HbookHistSvc' , 'RootHistSvc' ]
+HistogramPersis...  DEBUG Service base class initialized successfully
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+ToolSvc             DEBUG Service base class initialized successfully
+ToolSvc              INFO History Service not active - AlgTools not registered
+ClassIDSvc           INFO Initializing ClassIDSvc - package version CLIDComps-00-00-01
+ClassIDSvc          DEBUG Service base class initialized successfully
+ClassIDSvc           INFO  getRegistryEntries: read 196 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO ClassIDSvc Initialized successfully 
+ToolSvc.MyFolder    ERROR add: can not find type [Baricco] in clid db
+ToolSvc.MyFolder    ERROR add: can not find type [cucu] in clid db
+ToolSvc.MyFolder    ERROR add: can not find clid 56789401 in clid db
+8101/
+8101/Bla
+8107/
+8107/*
+8107/abcd
+*** SG::Folder_test OK ***

share/SGFolder_test.txt

+// common job opts for SG unit tests
+
+// $Id: SGFolder_test.txt,v 1.1.1.1 2007-06-22 23:21:47 calaf Exp $
+
+MessageSvc.OutputLevel = 2;
+ToolSvc.MyFolder.ItemList = { "Foo#Bla", "Bar#*", "8101", "8107#", "Baricco#*"};

src/ProxyProviderSvc.cxx

+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "SGTools/DataProxy.h"
+#include "SGTools/BaseInfo.h"
+
+#include "AthenaKernel/IAddressProvider.h"
+#include "AthenaKernel/IProxyRegistry.h"
+
+#include "GaudiKernel/IConversionSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/GaudiException.h"
+
+#include "ProxyProviderSvc.h"
+
+using namespace std;
+
+ProxyProviderSvc::ProxyProviderSvc(const std::string& name, 
+				   ISvcLocator* svcLoc): 
+  Service(name, svcLoc) 
+{
+  declareProperty("ProviderNames", m_providerNames);
+  m_providerNames.declareUpdateHandler(&ProxyProviderSvc::providerNamesPropertyHandler, this);
+}
+
+ProxyProviderSvc::~ProxyProviderSvc() {}
+
+StatusCode 
+ProxyProviderSvc::initialize() 
+{
+  MsgStream log(messageService(), name());
+  log << MSG::INFO << "Initializing " << name() 
+      << " - package version " << PACKAGE_VERSION 
+      << endreq;
+
+  const bool CREATEIF(true);
+  // cache pointer to Persistency Service
+  if (!(service("EventPersistencySvc", m_pDataLoader, CREATEIF)).isSuccess()) {
+    m_pDataLoader = 0;
+    MsgStream log( messageService(), name() );
+    log << MSG::ERROR
+	<< "Could not	 get pointer to Persistency Service"
+	<< endreq;
+    return StatusCode::FAILURE;;
+  } else {
+    MsgStream log( messageService(), name() );
+    log << MSG::VERBOSE
+	<< "Got pointer to Persistency Service " << m_pDataLoader
+	<< endreq;
+  }
+
+  //get properties set;	
+  if(!(Service::initialize()).isSuccess()) return StatusCode::FAILURE;
+
+
+  return StatusCode::SUCCESS;
+}
+
+///IProxyProvider interface
+/// add proxies (before Begin Event)
+StatusCode 
+ProxyProviderSvc::preLoadProxies(IProxyRegistry& store)
+{
+  StatusCode sc(StatusCode::SUCCESS);
+  pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
+  while (sc.isSuccess() && (iProvider != iEnd)) {
+    TAdList tList;
+    sc = (**iProvider).preLoadAddresses(store.storeID(), tList);
+    if (sc.isSuccess()) sc = addAddresses(store, *iProvider, tList);
+    ++iProvider;
+  }
+  MsgStream log(msgSvc(), name());
+  log << MSG::VERBOSE <<  "preLoadProxies returns " << sc<< endreq;
+  return sc;
+}
+
+
+///IProxyProvider interface
+///add proxies to the store to modify
+StatusCode 
+ProxyProviderSvc::loadProxies(IProxyRegistry& store)
+{
+  StatusCode sc(StatusCode::SUCCESS);
+  pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
+  while (sc.isSuccess() && (iProvider != iEnd)) {
+    TAdList tList;
+    sc = (**iProvider).loadAddresses(store.storeID(), tList);
+    if (sc.isSuccess()) sc = addAddresses(store, *iProvider, tList);
+    ++iProvider;
+  }
+  MsgStream log(msgSvc(), name());
+  log << MSG::VERBOSE <<  "loadProxies returns " << sc<< endreq;
+  return sc;
+}
+
+/// add a list of TADs to store.
+StatusCode ProxyProviderSvc::addAddresses(IProxyRegistry& store, 
+					  IAddressProvider* provider,
+					  TAdList& tList)
+{
+
+  TAdIterator iTAD(tList.begin()), endTAD(tList.end());
+  for (; iTAD != endTAD; iTAD++) {
+    SG::TransientAddress* pTAD = *iTAD;
+
+    SG::DataProxy* proxy = store.proxy_exact(pTAD->clID(), pTAD->name());
+    /// if proxy exists, simply update the proxy with new IOpaqueAddress, 
+    /// else construct a new proxy
+    if (0 != proxy) 
+    {
+      proxy->setAddress(pTAD->address());
+      delete pTAD;
+    } else {
+      pTAD->setProvider(provider);
+      if ( 0 == addAddress(store, pTAD) ) return StatusCode::FAILURE;
+    }
+  }
+
+  return StatusCode::SUCCESS;
+
+}
+
+///create a new Proxy, overriding CLID and/or key
+SG::DataProxy*
+ProxyProviderSvc::addAddress(IProxyRegistry& store, 
+			     SG::TransientAddress* tAddr) 
+{  
+  SG::DataProxy* dp = new SG::DataProxy(tAddr, m_pDataLoader, true, true);
+  //  store.addToStore(tAddr->clID(),dp);
+  //  MsgStream log(msgSvc(), name());
+  //  log << MSG::VERBOSE << "created proxy for " << tAddr->clID() << "/" << tAddr->name() << "using " << m_pDataLoader->repSvcType() << endreq;
+
+  // loop over all the transient CLIDs:
+  SG::TransientAddress::TransientClidSet tClid = tAddr->transientID();
+  SG::TransientAddress::TransientClidSet::const_iterator tIter = tClid.begin();
+  for (; tIter != tClid.end(); tIter++) {
+    (store.addToStore(*tIter, dp)).ignore();
+  }
+
+  // loop over all alias'
+  SG::TransientAddress::TransientAliasSet persAlias = tAddr->alias();
+  SG::TransientAddress::TransientAliasSet::const_iterator aliasIter = persAlias.begin();
+  for (; aliasIter != persAlias.end(); aliasIter++) {
+    (store.addAlias(*aliasIter, dp)).ignore();
+  }
+
+  // Add any other allowable conversions.
+  const SG::BaseInfoBase* bi = SG::BaseInfoBase::find (tAddr->clID());
+  if (bi) {
+    std::vector<CLID> base_clids = bi->get_bases();
+    for (unsigned i=0; i < base_clids.size(); i++)
+      if (tClid.find (base_clids[i]) == tClid.end())
+        store.addToStore (base_clids[i], dp).ignore();
+  }
+
+  return dp;
+}
+
+///get the default proxy from Provider
+SG::DataProxy* 
+ProxyProviderSvc::retrieveProxy(const CLID& id, const std::string& key,
+				IProxyRegistry& store)
+{
+
+  SG::DataProxy *dp;
+  if ( (dp=store.proxy(id,key)) != 0 ) return dp;
+
+  SG::TransientAddress* tAD = new SG::TransientAddress(id, key);
+  pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
+  for (; iProvider != iEnd; iProvider++) {
+    if ( ((*iProvider)->updateAddress(tAD)).isSuccess() ) 
+    {
+      tAD->setProvider(*iProvider);
+      return addAddress(store,tAD);
+    }
+  }  
+
+  delete tAD;
+  return 0;
+
+}
+
+StatusCode
+ProxyProviderSvc::updateAddress(SG::TransientAddress* tAD)
+{
+
+  pAPiterator iProvider(m_providers.begin()), iEnd(m_providers.end());
+  for (; iProvider != iEnd; iProvider++) {
+    if ( ((*iProvider)->updateAddress(tAD)).isSuccess() ) 
+    {
+      tAD->setProvider(*iProvider);
+      return StatusCode::SUCCESS;
+    }
+    ++iProvider;
+  }  
+
+  return StatusCode::SUCCESS;
+
+}
+
+/// Gaudi Service boilerplate
+/// Gaudi_cast...
+// N.B. Don't forget to release the interface after use!!!
+StatusCode 
+ProxyProviderSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) 
+{
+  if ( IProxyProviderSvc::interfaceID().versionMatch(riid) )    {
+    *ppvInterface = (IProxyProviderSvc*)this;
+  }
+  else  {
+    // Interface is not directly available: try out a base class
+    return Service::queryInterface(riid, ppvInterface);
+  }
+  addRef();
+  return StatusCode::SUCCESS;
+}
+
+
+void 
+ProxyProviderSvc::providerNamesPropertyHandler( Property& /*theProp*/ ) {
+  MsgStream log(messageService(), name());
+  //add declared providers to the list;
+  std::vector<std::string>::const_iterator iN(m_providerNames.value().begin());
+  std::vector<std::string>::const_iterator iEnd(m_providerNames.value().end());
+  while (iN != iEnd) {
+    IService *pIS(0);
+    IAddressProvider *pAP(0);
+    ListItem tn(*iN);
+    if (!(service(tn.type(), tn.name(), pIS)).isSuccess() ||
+	0 == (pAP = dynamic_cast<IAddressProvider*>(pIS))) {
+      log << MSG::ERROR << " getting Address Provider "<< *iN << endmsg; 
+      throw GaudiException("Failed to locate address provider",
+			   "ProxyProviderSvc::providerNamesPropertyHandle", 
+			   StatusCode::FAILURE);
+
+    } else {
+      log << MSG::DEBUG << " added Address Provider "<< pIS->name() << endmsg; 
+    }
+    addProvider(pAP);
+    ++iN;
+  }
+
+}
+

src/ProxyProviderSvc.h

+/** manages the address providers and add proxies on demand to the store
+  * ---------------------------------------------------------------------
+  * @author Paolo Calafiura <pcalafiura@lbl.gov> - ATLAS Collaboration
+  */
+
+// $Id: ProxyProviderSvc.h,v 1.1.1.1 2007-06-22 23:21:47 calaf Exp $
+
+#ifndef STOREGATE_PROXYPROVIDERSVC_H
+# define STOREGATE_PROXYPROVIDERSVC_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+#ifndef ATHENAKERNEL_IPROXYPROVIDERSVC_H
+ #include "AthenaKernel/IProxyProviderSvc.h"
+#endif
+#ifndef GAUDIKERNEL_SERVICE_H
+ #include "GaudiKernel/Service.h"
+#endif
+#ifndef GAUDIKERNEL_PROPERTY_H
+ #include "GaudiKernel/Property.h" /*StringArrayProperty*/
+#endif
+#ifndef KERNEL_STATUSCODES_H
+ #include "GaudiKernel/StatusCode.h"
+#endif
+#include <cassert>
+#ifndef _CPP_SET
+ #include <set>
+#endif
+#ifndef _CPP_STRING
+ #include <string>
+#endif
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< FORWARD DECLARATIONS                                           >>>>>>
+namespace SG {
+  class DataProxy;
+  class TransientAddress;
+}
+
+class IAddressProvider;
+class IProxyRegistry; //this is DataStore
+class IConversionSvc;
+class IOpaqueAddress;
+class ISvcLocator;
+template <class TYPE> class SvcFactory;
+
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+class ProxyProviderSvc : virtual public IProxyProviderSvc,
+			 public Service 
+{
+public:
+
+  typedef std::set<IAddressProvider*>::iterator  pAPiterator;
+  typedef std::list<SG::TransientAddress*> TAdList;
+  typedef TAdList::iterator TAdIterator;
+
+  ///IProxyProvider interface
+  //@{
+  ///add proxies to the store to modify (before Begin Event)
+  virtual StatusCode preLoadProxies(IProxyRegistry& storeToModify);
+
+  ///add proxies to the store to modify (during Begin Event)
+  virtual StatusCode loadProxies(IProxyRegistry& storeToModify);
+
+  ///get the default proxy. Optionally add proxies to the store to modify
+  virtual SG::DataProxy* retrieveProxy(const CLID& id, const std::string& key,
+				       IProxyRegistry& storeToModify);
+
+  /// update a transient Address
+  virtual StatusCode updateAddress(SG::TransientAddress* tad);
+
+ ///create a list of transient Addresses:
+  StatusCode addAddresses(IProxyRegistry& dataStore,
+			  IAddressProvider* iap,
+			  TAdList& tad);
+
+  ///create a new Proxy, overriding CLID and/or key
+  SG::DataProxy* addAddress(IProxyRegistry& storeToModify, 
+			    SG::TransientAddress* tad);
+  //@}
+
+
+  ///IAddressProvider manager functionality
+  ///add a provider to the set of known ones. PROVIDER IS OWNED BY THE CLIENT
+  virtual void addProvider(IAddressProvider* aProvider);
+
+  /// Service boilerplate
+  //@{
+  virtual StatusCode initialize();
+  virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface );
+  //@}
+
+protected:    
+  /// the Service Factory
+  friend class SvcFactory<ProxyProviderSvc>;
+  /// Standard Service Constructor
+  ProxyProviderSvc(const std::string& name, ISvcLocator* svcLoc);
+  virtual ~ProxyProviderSvc();
+
+private:
+  /// the services declared as providers
+  StringArrayProperty m_providerNames;
+  /// the handler for m_providerNames
+  void providerNamesPropertyHandler( Property& theProp );
+  
+  /// the providers we know about. WE DON'T OWN THEM
+  std::set<IAddressProvider*> m_providers; 
+  /// Persistency Service
+  IConversionSvc* m_pDataLoader;   
+};
+
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+inline void ProxyProviderSvc::addProvider(IAddressProvider* aProvider) {
+  assert(aProvider);
+  m_providers.insert(aProvider);
+}
+
+#endif // STOREGATE_PROXYPROVIDERSVC_H
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <iostream>
+#include <vector>
+
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "GaudiKernel/IMessageSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ISvcLocator.h"
+
+#include "AthenaKernel/DefaultKey.h"
+#include "AthenaKernel/IClassIDSvc.h"
+
+#include "AthenaKernel/IClassIDSvc.h"
+#include "CLIDSvc/tools/ClassID_traits.h"
+
+#include "SGFolder.h"
+
+/* #define SGFOLDER_DEBUG 1 */
+
+using namespace SG;
+
+
+
+Folder::Folder( const std::string& type, 
+		const std::string& name,
+		const IInterface* parent) : 
+  AlgTool( type, name, parent ), m_pCLIDSvc("ClassIDSvc", name)
+{
+  declareProperty("ItemList", m_itemList).ignore();
+  m_itemList.declareUpdateHandler(&Folder::decodeItemList, this);
+}
+
+
+//-----------------------------------------------------------------------------
+StatusCode Folder::queryInterface(const InterfaceID& riid, void** ppvIf) {
+  if ( riid == SG::IFolder::interfaceID() ) {
+    *ppvIf = (IFolder*)this;
+    addRef();
+    return StatusCode::SUCCESS;
+  }
+  return AlgTool::queryInterface( riid, ppvIf );
+}
+
+//-----------------------------------------------------------------------------
+StatusCode Folder::initialize() {
+  return m_pCLIDSvc.retrieve();
+}
+
+//-----------------------------------------------------------------------------
+void Folder::decodeItemList(Property&) {
+  std::for_each(m_itemList.value().begin(), m_itemList.value().end(),  
+		std::bind1st(std::mem_fun(&Folder::decodeItem), this)); //HS!
+}
+
+void Folder::decodeItem(std::string item) {
+  assert( !item.empty() );
+  assert( m_pCLIDSvc );
+#ifdef SGFOLDER_DEBUG
+  //can't use MsgStream (log level still not defined)
+  std::cout << "Folder::decodeItem("<< item<<") called" << std::endl;
+#endif
+  std::string::size_type sep(item.rfind('#'));
+  std::string typeName (item.substr(0,sep));
+  std::string skey;
+  if (sep != std::string::npos) skey = item.substr(sep+1);
+
+  //item contains a typename OR a CLID. Try the CLID hypothesis first 
+  CLID clid(atoi(typeName.c_str()));  
+  if ( !add(clid, skey).isSuccess() ) { 
+    //lets see if it is a type name then
+    add(typeName, skey).ignore();
+  }
+}
+
+StatusCode 
+Folder::add(const std::string& typeName, const std::string& skey) {
+  CLID clid;
+  StatusCode sc(m_pCLIDSvc->getIDOfTypeName(typeName, clid));
+  if (sc.isSuccess()) sc=add(clid, skey);
+  else {
+    MsgStream log(msgSvc(), name());
+    log << MSG::ERROR << "add: can not find type ["
+	<< typeName << "] in clid db" << endreq;
+  }
+  return sc;
+}
+
+StatusCode
+Folder::add(const CLID& clid, const std::string& skey) {
+  StatusCode sc(StatusCode::FAILURE);
+  if ( m_pCLIDSvc->isIDInUse(clid) ) {
+    m_list.insert(FolderItem(clid, skey));
+    sc = StatusCode::SUCCESS;
+  } else if (0 != clid) {
+    MsgStream log(msgSvc(), name());
+    log << MSG::ERROR << "add: can not find clid "
+	<< clid << " in clid db" << endreq;
+  }
+#ifdef SGFOLDER_DEBUG
+    std::cout << "SG::Folder::add(" << clid << ",\"" << skey << "\") returns " 
+	      << (sc.isSuccess() ? "SUCCESS" : "FAILURE") << std::endl;
+#endif     
+  return sc;
+}
+#ifndef SGTOOLS_FOLDER_H
+#define SGTOOLS_FOLDER_H
+
+#include <string>
+
+#include "GaudiKernel/AlgTool.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "SGTools/SGIFolder.h"
+
+class IClassIDSvc;
+
+namespace SG {
+
+  /** @class SG::Folder
+   * @brief a run-time configurable list of data objects
+   *
+   * @author pcalafiura@lbl.gov - ATLAS Collaboration
+   * $Id: SGFolder.h,v 1.1.1.1 2007-06-22 23:21:48 calaf Exp $
+   **/
+  class Folder : public virtual IFolder, public virtual AlgTool
+  {
+  public:
+    /// \name structors
+    //@{
+    Folder(const std::string& name, 
+	   const std::string& type,
+	   const IInterface* parent);
+    virtual ~Folder() {};
+    //@}
+
+    /// the list we manage
+    typedef IFolder::ItemList ItemList;
+
+    /// \name access the ItemList
+    //@{
+    typedef IFolder::const_iterator const_iterator;
+    virtual const_iterator begin() const { return m_list.begin(); }
+    virtual const_iterator end() const { return m_list.end(); }
+    //@}
+
+    ///add a data object identifier to the list
+    virtual StatusCode add(const std::string& typeName, const std::string& skey);
+    ///add a data object identifier to the list
+    virtual StatusCode add(const CLID& clid, const std::string& skey);
+
+    /// \name AlgTool boilerplate 
+    //@{
+    virtual StatusCode initialize();
+    /// Query for a given interface
+    virtual StatusCode queryInterface(const InterfaceID& , void** ); 
+    //@}
+
+  private:
+    ServiceHandle<IClassIDSvc> m_pCLIDSvc;
+    StringArrayProperty m_itemList;
+    void decodeItemList(Property&);
+    void decodeItem(std::string); //FIXME
+    ItemList m_list; 
+
+  };
+} //ns SG
+
+#endif

src/components/SGComps_entries.cxx

+#include "../ProxyProviderSvc.h"
+#include "../SGFolder.h"
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+DECLARE_SERVICE_FACTORY( ProxyProviderSvc )
+DECLARE_NAMESPACE_TOOL_FACTORY(SG, Folder )
+
+DECLARE_FACTORY_ENTRIES(SGComps) {
+    DECLARE_SERVICE( ProxyProviderSvc )
+    DECLARE_NAMESPACE_TOOL( SG, Folder )
+}

src/components/SGComps_load.cxx

+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(SGComps)
+

test/ProxyProviderSvc_test.cxx

+/***************************************************************************
+ unit test for the proxy provide mechanism
+ -----------------------------------------
+ ATLAS Collaboration
+ ***************************************************************************/
+
+// $Id: ProxyProviderSvc_test.cxx,v 1.1.1.1 2007-06-22 23:21:48 calaf Exp $
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "../src/ProxyProviderSvc.h"
+
+#include <cassert>
+#include <iostream>
+#include <string>
+
+#include "TestTools/initGaudi.h"
+#include "TestTools/SGassert.h"
+#include "ToyConversion/FooBar.h"
+#include "ToyConversion/ToyConversionSvc.h"
+
+#include "SGTools/TransientAddress.h"
+#include "SGTools/DataProxy.h"
+
+#include "StoreGate/StoreGateSvc.h"
+#include "CLIDSvc/tools/ClassID_traits.h"
+#include "AthenaKernel/IAddressProvider.h"
+#include "AthenaKernel/StoreID.h"
+
+#include "GaudiKernel/GenericAddress.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/ClassID.h"
+
+
+#include <string>
+
+using namespace Athena_test;
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::string;
+using SG::DataProxy;
+using SG::TransientAddress;
+
+class FooBar {};
+#include "CLIDSvc/CLASS_DEF.h"
+CLASS_DEF(FooBar, 8109, 0)
+
+template <typename PROXIED>
+class TestProvider : public IAddressProvider {
+public:
+  TestProvider(string key) :
+    m_ID(ClassID_traits<PROXIED>::ID()), m_key(key) 
+  {
+    m_IOA = new GenericAddress(ToyConversionSvc::storageType(),
+			       m_ID,m_key);
+  }
+  virtual ~TestProvider() {}
+  ///get all addresses that the provider wants to preload in SG maps
+
+  virtual StatusCode loadAddresses(StoreID::type /*id*/, tadList& /* tList */) 
+  {return StatusCode::SUCCESS;}
+
+  virtual StatusCode preLoadAddresses(StoreID::type /*id*/, tadList& tList) 
+  {
+    TransientAddress* tad = new TransientAddress(m_ID, m_key, m_IOA);
+    tList.push_back(tad);
+    return StatusCode::SUCCESS;
+  }
+
+  ///get a specific address, plus all others  the provider wants to load in SG maps
+  virtual StatusCode updateAddress(TransientAddress* tad)
+  { 
+    
+    if ((tad->clID() != m_ID) || (tad->name() != m_key)) {
+//        cout << "m_ID: " << m_ID.clID() << " " << m_ID.key() << endl;
+//        cout << "id: " << id.clID() << " " << id.key() << endl;
+      return StatusCode::FAILURE;
+    } else {
+      tad->setAddress(m_IOA);
+    }
+      return StatusCode::SUCCESS;
+  }
+      
+private:
+  CLID m_ID;
+  std::string m_key;
+  IOpaqueAddress* m_IOA;
+};
+
+
+int main() {
+  ISvcLocator* pSvcLoc(0);
+  if (!initGaudi("ProxyProviderSvc_test.txt", pSvcLoc)) {
+    cerr << "This test can not be run" << endl;
+    return 0;
+  }  
+  assert( pSvcLoc );
+
+  StoreGateSvc* pStore(0);
+  static const bool CREATE(true);
+  assert( (pSvcLoc->service("StoreGateSvc", pStore, CREATE)).isSuccess() );
+  assert( pStore );
+  IProxyProviderSvc* pIPPSvc;
+  assert( (pSvcLoc->service("ProxyProviderSvc", pIPPSvc, CREATE)).isSuccess() );
+  assert( pIPPSvc );
+
+  ProxyProviderSvc* pPPSvc = dynamic_cast<ProxyProviderSvc*>(pIPPSvc);
+  assert( pPPSvc );
+
+  pPPSvc->addProvider(new TestProvider<Foo>("aFoo"));
+  pPPSvc->addProvider(new TestProvider<Bar>("aBar"));
+  pPPSvc->addProvider(new TestProvider<FooBar>("aFooBar"));
+
+
+  DataHandle<Bar> hBar;
+  assert( (pStore->bind(hBar, "aBar")).isSuccess() );
+  
+  assert( hBar.ID() == "aBar" );
+
+  assert( hBar.cptr() );
+
+  cout << pStore->dump() << endl;
+
+  assert( !(pStore->transientContains<Foo>("aFoo")) );
+  assert( pStore->contains<Foo>("aFoo") );
+
+  const Foo* pFoo(0);
+  assert( (pStore->retrieve(pFoo, "aFoo")).isSuccess() );
+  assert( pFoo );
+
+
+  const FooBar* pFooBar(0);
+  SGASSERTERROR( (pStore->retrieve(pFooBar, "aFooBar")).isSuccess() );
+  assert( 0 == pFooBar );
+
+  cout << "*** ProxyProviderSvc_test OK ***" <<endl;
+  return 0;
+}
+
+<?xml version="1.0"?>
+<atn>
+    <TEST name="SGCompsTest" type="makecheck" suite="Examples">
+       <package>Control/SGComps</package>
+       <timelimit>5</timelimit>
+       <author> Paolo Calafiura </author>
+       <mailto> pcalafiura@lbl.gov</mailto>
+       <expectations>
+          <errorMessage>Athena exited abnormally</errorMessage>
+          <warningMessage> # WARNING_MESSAGE : post.sh> ERROR</warningMessage>
+          <successMessage>check ok</successMessage>
+          <returnValue>0</returnValue>
+       </expectations>
+    </TEST>
+</atn>

test/SGFolder_test.cxx

+#undef NDEBUG
+
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <string>
+#include "TestTools/initGaudi.h"
+#include "GaudiKernel/ToolHandle.h"
+
+// TEST_FOOBAR_H
+
+#include "CLIDSvc/CLASS_DEF.h"
+struct Foo{
+  void doNothing() const {};
+};
+CLASS_DEF( Foo, 8101, 0) 
+struct Bar{
+  void doNothing() const {};
+};
+CLASS_DEF( Bar, 8107, 0) 
+
+// TEST_FOOBAR_H
+
+
+#include "SGTools/SGIFolder.h"
+
+class ISvcLocator;
+
+using namespace std;
+
+int main () {
+  cerr << "*** SG::Folder_test starts ***" <<endl;
+  ISvcLocator* pDummy;
+  if (!Athena_test::initGaudi("SGFolder_test.txt", pDummy)) {
+    std::cerr << " This test cannot be run without init Gaudi" << endl;
+    return -1;
+  }
+  ToolHandle<SG::IFolder> pFolder("SG::Folder/MyFolder");
+  assert( pFolder.retrieve().isSuccess() );
+  //this of course depends on the job opts
+  assert( 4 == std::distance(pFolder->begin(), pFolder->end()) );
+
+  assert( (pFolder->add("Bar", "abcd")).isSuccess() );
+  assert( (pFolder->add("cucu", "")).isFailure() );
+  assert( (pFolder->add(56789401, "34")).isFailure() ); 
+  assert( 5 == std::distance(pFolder->begin(), pFolder->end()) );
+
+  SG::IFolder::const_iterator i(pFolder->begin()), iEnd(pFolder->end());
+  while (i != iEnd) {
+    cout << i->id() << "/" << i->key() << endl;
+    ++i;
+  }
+  cerr << "*** SG::Folder_test OK ***" <<endl;
+  return 0;
+
+}
+
+