Commits

Anonymous committed 836512b

function to clone a service including its properties

  • Participants
  • Parent commits 50f3dde

Comments (0)

Files changed (2)

File AthenaServices/CloneService.h

+#include "GaudiKernel/StatusCode.h"
+#include <string>
+class Service;
+namespace CloneService {
+  /** given a reference to a parent svc sets a reference to a cloned child */
+  StatusCode clone(const Service* parent, const std::string& childName,
+		   Service*& child);
+}

File src/CloneService.cxx

+#include <cassert>
+#include <vector>
+#include "AthenaServices/CloneService.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/ISvcManager.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Service.h"
+#include "GaudiKernel/SmartIF.h"
+#include "GaudiKernel/System.h"
+
+namespace CloneService {
+  /** given a pointer to a parent svc sets a reference to a cloned child */
+  StatusCode clone(const Service* parent, const std::string& childName,
+		   Service*& child) 
+  {
+    //FIXME this only creates an uninitialized SERVICE. 
+    //FIXME it would be better if one could say parent->clone()
+    //FIXME (its default implementation could be this one)
+
+    //check the parent pointer is valid
+    assert (0 != parent);
+
+    MsgStream log( parent->msgSvc(), "CloneService::clone" );
+
+    // can we access the Service locator interface?
+    ISvcLocator* svcLoc(parent->serviceLocator());
+    assert (0 != svcLoc);
+
+    // can we access the Service Manager interface?
+    SmartIF<ISvcManager> svcMgr(IID_ISvcManager, svcLoc);
+    if ( !svcMgr.isValid() ) 
+      {
+	log << MSG::FATAL 
+	    << "ISvcManager interface not found by serviceLocator." 
+	    << endreq;
+	return StatusCode::FAILURE;
+      }
+    //create the child unless it is already there
+    //if the service is not there and can't be created barf
+    IService* pIS(0);
+    if ((svcLoc->getService(childName, pIS)).isSuccess() &&
+	0 != (child = dynamic_cast<Service*>(pIS))) {
+      log << MSG::DEBUG 
+	  << "Found service " << childName
+	  << endreq;
+    } else {
+      const std::string& parentType = System::typeinfoName(typeid(*parent));
+      if (svcMgr->createService(parentType, childName,
+				pIS).isSuccess() &&
+	  0 != (child = dynamic_cast<Service*>(pIS))) {
+	log << MSG::DEBUG 
+	    << "Created service " << childName << " of type " << parentType
+	    << endreq;
+      } else {
+	log << MSG::ERROR
+	    << "Failed to create " << childName << " of type " << parentType 
+	    << endreq;
+	return StatusCode::FAILURE;
+      }
+
+    }
+    //now copy parent's properties into child
+    std::vector<Property*>::const_iterator iProp(parent->getProperties().begin());
+    std::vector<Property*>::const_iterator eProp(parent->getProperties().end());
+    while (iProp != eProp &&
+	   (child->setProperty(**iProp)).isSuccess()) ++iProp;
+    if (iProp != eProp) {
+      log << MSG::ERROR 
+	  << "Failed to set child property " << (**iProp).name() 
+	  << endreq;
+      return StatusCode::FAILURE;
+    } else {
+      log << MSG::DEBUG 
+	  << childName << " properties set"
+	  << endreq;
+    }
+
+    //finally put the service in the same state as the parent
+    if (IService::INITIALIZED == parent->state())
+      return child->initialize();  //this is the only defined state so far
+    else {
+      log << MSG::DEBUG 
+	  << "Initialized " <<  childName
+	  << endreq;
+      return StatusCode::SUCCESS;
+    }
+  }
+}