![]() |
|
|
Generated: 8 Jan 2009 |
00001 //$Id: EventCollectionSelector.cpp,v 1.16 2007/01/09 16:54:47 hmd Exp $ 00002 00003 // Include files 00004 #include "GaudiKernel/SmartIF.h" 00005 #include "GaudiKernel/SvcFactory.h" 00006 #include "GaudiKernel/ObjectFactory.h" 00007 #include "GaudiKernel/GenericAddress.h" 00008 #include "GaudiKernel/MsgStream.h" 00009 #include "GaudiKernel/IRegistry.h" 00010 #include "GaudiKernel/INTupleSvc.h" 00011 #include "GaudiKernel/ISvcLocator.h" 00012 #include "GaudiKernel/IDataSourceMgr.h" 00013 #include "GaudiKernel/IAddressCreator.h" 00014 #include "GaudiKernel/ISelectStatement.h" 00015 #include "GaudiKernel/NTuple.h" 00016 #include "GaudiKernel/EventSelectorDataStream.h" 00017 00018 #include "EventCollectionSelector.h" 00019 00020 #include <memory> 00021 00022 DECLARE_SERVICE_FACTORY(EventCollectionSelector) 00023 00024 00029 class EventCollectionContext : public IEvtSelector::Context { 00030 public: 00031 typedef std::list<std::string> ListName; 00032 private: 00033 GenericAddress* m_pAddressBuffer; 00034 const EventCollectionSelector* m_pSelector; 00035 ListName m_files; 00036 std::string m_criteria; 00037 ListName::const_iterator m_fileIterator; 00038 std::string m_currentInput; 00039 00040 public: 00042 EventCollectionContext(const EventCollectionSelector* pSelector); 00044 virtual ~EventCollectionContext(); 00045 const std::string& currentInput() const { 00046 return m_currentInput; 00047 } 00048 void setCurrentInput(const std::string& v) { 00049 m_currentInput = v; 00050 } 00051 ListName& files() { 00052 return m_files; 00053 } 00054 virtual void* identifier() const { 00055 return (void*)m_pSelector; 00056 } 00057 void setCriteria(const std::string& crit) { 00058 m_criteria = crit; 00059 } 00060 ListName::const_iterator fileIterator() { 00061 return m_fileIterator; 00062 } 00063 void setFileIterator(ListName::const_iterator new_iter) 00064 { m_fileIterator = new_iter; } 00065 }; 00066 00067 EventCollectionContext::~EventCollectionContext() { 00068 m_pAddressBuffer->release(); 00069 } 00070 00071 EventCollectionContext::EventCollectionContext(const EventCollectionSelector* pSelector) 00072 : m_pSelector(pSelector) 00073 { 00074 m_pAddressBuffer = new GenericAddress(); 00075 m_pAddressBuffer->addRef(); 00076 } 00077 00078 // Standard constructor 00079 EventCollectionSelector::EventCollectionSelector(const std::string& name, ISvcLocator* svcloc ) 00080 : Service( name, svcloc), m_tupleSvc(0) 00081 { 00082 m_pAddrCreator = 0; 00083 declareProperty("CnvService", m_tupleSvcName = "EvtTupleSvc"); 00084 declareProperty("Authentication",m_authentication= ""); 00085 declareProperty("Container", m_cntName = "B2PiPi"); 00086 declareProperty("Item", m_itemName = "Address"); 00087 declareProperty("Criteria", m_criteria = ""); 00088 declareProperty("DB", m_database = ""); 00089 declareProperty("DbType", m_dbType = ""); 00090 declareProperty("Function", m_statement= "NTuple::Selector"); 00091 } 00092 00093 EventCollectionSelector::~EventCollectionSelector() { 00094 } 00095 00096 // IService implementation: Db event selector override 00097 StatusCode EventCollectionSelector::initialize() { 00098 // Initialize base class 00099 StatusCode status = Service::initialize(); 00100 MsgStream log(messageService(), name()); 00101 if ( !status.isSuccess() ) { 00102 log << MSG::ERROR << "Error initializing base class Service!" << endreq; 00103 return status; 00104 } 00105 status = serviceLocator()->service("EventPersistencySvc", m_pAddrCreator, true ); 00106 if( !status.isSuccess() ) { 00107 log << MSG::ERROR << "Unable to locate IAddressCreator interface of " << "EventPersistencySvc" << endreq; 00108 return status; 00109 } 00110 status = serviceLocator()->service(m_tupleSvcName, m_tupleSvc, true ); 00111 if( !status.isSuccess() ) { 00112 log << MSG::ERROR << "Unable to locate INTupleSvc interface of " << m_tupleSvcName << endreq; 00113 return status; 00114 } 00115 return status; 00116 } 00117 00118 // Connect collection to selector 00119 StatusCode 00120 EventCollectionSelector::connectDataSource(const std::string& db, const std::string& /* typ */ ) const { 00121 StatusCode status = StatusCode::FAILURE; 00122 SmartIF<IDataSourceMgr> svc(IID_IDataSourceMgr, m_tupleSvc); 00123 if ( svc.isValid( ) && db.length() > 0 ) { 00124 std::string ident = name() + ' '; 00125 ident += "DATAFILE='" + m_database.substr(5,m_database.length()) + "' "; 00126 ident += "TYP='" + m_dbType + "' "; 00127 ident += "OPT='READ' "; 00128 if ( m_authentication.length() > 0 ) { 00129 ident += "AUTH='" + m_authentication + "' "; 00130 } 00131 status = svc->connect(ident); 00132 } 00133 return status; 00134 } 00135 00137 StatusCode 00138 EventCollectionSelector::connectTuple(const std::string& nam, const std::string& itName, NTuple::Tuple*& tup, NTuple::Item<IOpaqueAddress*>*& item) const { 00139 std::string top = "/NTUPLES/" + name() + '/' + nam; 00140 StatusCode status = m_tupleSvc->retrieveObject(top, (DataObject*&)tup); 00141 if ( status.isSuccess() ) { 00142 item = new NTuple::Item<IOpaqueAddress*>(); 00143 status = tup->item(itName, *item); 00144 if ( status.isSuccess() ) { 00145 return status; 00146 } 00147 else { 00148 MsgStream log(msgSvc(), name()); 00149 log << MSG::ERROR << "Item " << itName << " is not part of the collection:" << top << endreq; 00150 } 00151 delete item; 00152 item = 0; 00153 } 00154 else { 00155 MsgStream err(msgSvc(), name()); 00156 err << MSG::ERROR << "Cannot connect to collection:" << top << endreq; 00157 } 00158 tup = 0; 00159 return status; 00160 } 00161 00163 StatusCode 00164 EventCollectionSelector::connectStatement(const std::string& typ, const std::string& crit, INTuple* tuple) const { 00165 std::string seltyp = typ; 00166 if ( seltyp.length() > 0 || crit.length() > 0 ) { 00167 if ( crit.length() > 0 && seltyp.length() == 0 ) seltyp = "NTuple::Selector"; 00168 SmartIF<ISelectStatement> stmt(IID_ISelectStatement, 00169 ROOT::Reflex::PluginService::Create<IInterface*>(seltyp, (IInterface*)serviceLocator())); 00170 if ( stmt.isValid( ) ) { 00171 if ( crit.length() > 0 ) stmt->setCriteria(crit); 00172 tuple->attachSelector(stmt).ignore(); 00173 return StatusCode::SUCCESS; 00174 } 00175 return StatusCode::FAILURE; 00176 } 00177 return StatusCode::SUCCESS; 00178 } 00179 00181 StatusCode EventCollectionSelector::getNextRecord(NTuple::Tuple* tuple) const { 00182 StatusCode status = StatusCode::FAILURE; 00183 if ( 0 != tuple ) { 00184 do { 00185 status = m_tupleSvc->readRecord(tuple); 00186 if ( status.isSuccess() ) { 00187 ISelectStatement* statement = tuple->selector(); 00188 bool use_it = (statement) ? (*statement)(tuple) : true; 00189 if ( use_it ) { 00190 return status; 00191 } 00192 } 00193 } while ( status.isSuccess() ); 00194 } 00195 return status; 00196 } 00197 00199 StatusCode EventCollectionSelector::getPreviousRecord(NTuple::Tuple* tuple ) const { 00200 StatusCode status = StatusCode::FAILURE; 00201 if ( tuple ) { 00202 IRegistry* pReg = tuple->registry(); 00203 if ( pReg ) { 00204 IOpaqueAddress* pAddr = pReg->address(); 00205 if ( pAddr ) { 00206 long* ip = (long*)pAddr->ipar(); 00207 do { 00208 if ( ip[1] > 1 ) { 00209 ip[1] -= 2; 00210 status = m_tupleSvc->readRecord(tuple); 00211 if ( status.isSuccess() ) { 00212 ISelectStatement* statement = tuple->selector(); 00213 bool use_it = (statement) ? (*statement)(tuple) : true; 00214 if ( use_it ) { 00215 return status; 00216 } 00217 } 00218 } 00219 else { 00220 return StatusCode::FAILURE; 00221 } 00222 } while ( status.isSuccess() ); 00223 } 00224 } 00225 } 00226 return StatusCode::FAILURE; 00227 } 00228 00229 // Connect collection to selector 00230 StatusCode EventCollectionSelector::connectCollection(MyContextType* ctxt) const 00231 { 00232 if ( ctxt ) { 00233 StatusCode status = connectDataSource(m_database, m_dbType); 00234 if ( status.isSuccess() ) { 00235 status = connectTuple(m_cntName, m_itemName, ctxt->tuple, ctxt->item); 00236 if ( status.isSuccess() ) { 00237 status = connectStatement(m_statement, m_criteria, ctxt->tuple); 00238 if ( status.isSuccess() ) { 00239 *(ctxt->item) = 0; 00240 return status; 00241 } 00242 } 00243 } 00244 return status; 00245 } 00246 return StatusCode::FAILURE; 00247 } 00248 00249 // Finalize service 00250 StatusCode EventCollectionSelector::finalize() { 00251 if ( m_pAddrCreator ) { 00252 m_pAddrCreator->release(); 00253 m_pAddrCreator = 0; 00254 } 00255 if ( m_tupleSvc ) { 00256 m_tupleSvc->release(); 00257 m_tupleSvc = 0; 00258 } 00259 return Service::finalize(); 00260 } 00261 00263 StatusCode 00264 EventCollectionSelector::createContext(Context*& refpCtxt) const 00265 { 00266 refpCtxt = 0; 00267 std::auto_ptr<MyContextType> ctxt(new MyContextType()); 00268 StatusCode status = connectCollection(ctxt.get()); 00269 if( !status.isSuccess() ) { 00270 MsgStream log(msgSvc(), name()); 00271 log << MSG::ERROR << "Unable to connect Collection file \"" << m_database << "\"" << endreq; 00272 return status; 00273 } 00274 refpCtxt = ctxt.release(); 00275 return StatusCode::SUCCESS; 00276 } 00277 00279 StatusCode 00280 EventCollectionSelector::next(Context& refCtxt) const 00281 { 00282 return next(refCtxt, 1); 00283 } 00284 00286 StatusCode 00287 EventCollectionSelector::next(Context& refCtxt,int jump) const 00288 { 00289 MyContextType *ctxt = dynamic_cast<MyContextType*>(&refCtxt); 00290 if ( ctxt ) { 00291 *(ctxt->item) = ctxt->addressBuffer; 00292 StatusCode sc = StatusCode::SUCCESS; 00293 for ( int i=0; i<jump && sc.isSuccess(); ++i ) { 00294 sc = getNextRecord(ctxt->tuple); 00295 } 00296 return sc; 00297 } 00298 return StatusCode::FAILURE; 00299 } 00300 00302 StatusCode 00303 EventCollectionSelector::previous(Context& refCtxt) const 00304 { 00305 return previous(refCtxt, 1); 00306 } 00307 00309 StatusCode 00310 EventCollectionSelector::previous(Context& refCtxt,int jump) const 00311 { 00312 MyContextType *ctxt = dynamic_cast<MyContextType*>(&refCtxt); 00313 if ( ctxt ) { 00314 *(ctxt->item) = ctxt->addressBuffer; 00315 StatusCode sc = StatusCode::SUCCESS; 00316 for ( int i=0; i<jump && sc.isSuccess(); ++i ) { 00317 sc = getPreviousRecord(ctxt->tuple); 00318 } 00319 return sc; 00320 } 00321 return StatusCode::FAILURE; 00322 } 00323 00325 StatusCode 00326 EventCollectionSelector::rewind(Context& /* refCtxt */ ) const 00327 { 00328 return StatusCode::FAILURE; 00329 } 00330 00332 StatusCode 00333 EventCollectionSelector::createAddress(const Context& refCtxt, IOpaqueAddress*& refpAddr) const 00334 { 00335 const MyContextType* ctxt = dynamic_cast<const MyContextType*>(&refCtxt); 00336 if ( ctxt ) { 00337 IOpaqueAddress* pA = *(ctxt->item); 00338 if ( pA ) { 00339 IOpaqueAddress* pAddress = 0; 00340 StatusCode status = m_pAddrCreator->createAddress(pA->svcType(), 00341 pA->clID(), 00342 pA->par(), 00343 pA->ipar(), 00344 pAddress); 00345 if ( status.isSuccess() ) { 00346 refpAddr = pAddress; 00347 return StatusCode::SUCCESS; 00348 } 00349 else { 00350 MsgStream log(msgSvc(), name()); 00351 log << MSG::ERROR << "Failed to access " << pA->par()[0] 00352 << ":" << pA->par()[1] 00353 << " SvcTyp:" << long(pA->svcType()) 00354 << " CLID:" << pA->clID() 00355 << endreq; 00356 } 00357 } 00358 } 00359 return StatusCode::FAILURE; 00360 } 00361 00363 StatusCode 00364 EventCollectionSelector::releaseContext(Context*& refCtxt) const 00365 { 00366 MyContextType *ctxt = dynamic_cast<MyContextType*>(refCtxt); 00367 if ( ctxt ) { 00368 delete ctxt; 00369 ctxt = 0; 00370 return StatusCode::SUCCESS; 00371 } 00372 return StatusCode::FAILURE; 00373 } 00374 00377 StatusCode 00378 EventCollectionSelector::resetCriteria(const std::string& cr,Context& refCtxt) const 00379 { 00380 MyContextType *ctxt = dynamic_cast<MyContextType*>(&refCtxt); 00381 if ( ctxt ) { 00382 ctxt->criteria = cr; 00383 return StatusCode::SUCCESS; 00384 } 00385 return StatusCode::FAILURE; 00386 } 00387 00389 StatusCode 00390 EventCollectionSelector::last(Context& /* refCtxt */ ) const 00391 { 00392 return StatusCode::FAILURE; 00393 } 00394 00395 // Service override: queryInterface 00396 StatusCode EventCollectionSelector::queryInterface(const InterfaceID& riid, void** ppvInterface) { 00397 if ( riid == IID_IEvtSelector ) { 00398 *ppvInterface = (IEvtSelector*)this; 00399 addRef(); 00400 return SUCCESS; 00401 } 00402 return Service::queryInterface( riid, ppvInterface ); 00403 } 00404