00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define PERSISTENCYSVC_PERSISTENCYSVC_CPP
00019
00020
00021 #include "GaudiKernel/SmartIF.h"
00022 #include "GaudiKernel/SvcFactory.h"
00023 #include "GaudiKernel/CnvFactory.h"
00024 #include "GaudiKernel/DataObject.h"
00025 #include "GaudiKernel/IConverter.h"
00026 #include "GaudiKernel/ISvcLocator.h"
00027 #include "GaudiKernel/IDataSelector.h"
00028 #include "GaudiKernel/IOpaqueAddress.h"
00029 #include "GaudiKernel/MsgStream.h"
00030 #include "GaudiKernel/strcasecmp.h"
00031 #include "GaudiKernel/TypeNameString.h"
00032 #include "GaudiKernel/IDataProviderSvc.h"
00033
00034
00035 #include "PersistencySvc.h"
00036
00037 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
00038 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
00039
00040 #define DEBMSG ON_DEBUG debug()
00041 #define VERMSG ON_VERBOSE verbose()
00042
00043
00044
00045 DECLARE_SERVICE_FACTORY(PersistencySvc)
00046
00047 enum CnvSvcAction {
00048 CREATE_OBJ,
00049 FILL_OBJ_REFS,
00050 UPDATE_OBJ,
00051 UPDATE_OBJ_REFS,
00052 CREATE_REP,
00053 FILL_REP_REFS,
00054 UPDATE_REP,
00055 UPDATE_REP_REFS
00056 };
00057
00058 StatusCode PersistencySvc::makeCall(int typ,
00059 IOpaqueAddress*& pAddress,
00060 DataObject*& pObject) {
00061 if ( m_enable ) {
00062 IConversionSvc* svc = 0;
00063 switch(typ) {
00064 case CREATE_REP:
00065 case FILL_REP_REFS:
00066 case UPDATE_REP:
00067 case UPDATE_REP_REFS:
00068 svc = m_cnvDefault;
00069 break;
00070 default:
00071 if ( 0 != pAddress ) {
00072 long svc_type = pAddress->svcType();
00073 svc = service(svc_type);
00074 if ( 0 == svc ) {
00075 return BAD_STORAGE_TYPE;
00076 }
00077 }
00078 else {
00079 return INVALID_ADDRESS;
00080 }
00081 break;
00082 }
00083
00084 StatusCode status(StatusCode::FAILURE,true);
00085 switch( typ ) {
00086 case CREATE_OBJ:
00087 pObject = 0;
00088 status = svc->createObj(pAddress, pObject);
00089 break;
00090 case FILL_OBJ_REFS:
00091 status = svc->fillObjRefs(pAddress, pObject);
00092 break;
00093 case UPDATE_OBJ:
00094 status = svc->updateObj(pAddress, pObject);
00095 break;
00096 case UPDATE_OBJ_REFS:
00097 status = svc->updateObjRefs(pAddress, pObject);
00098 break;
00099 case CREATE_REP:
00100 status = svc->createRep(pObject, pAddress);
00101 break;
00102 case FILL_REP_REFS:
00103 status = svc->fillRepRefs(pAddress, pObject);
00104 break;
00105 case UPDATE_REP:
00106 status = svc->updateRep(pAddress, pObject);
00107 break;
00108 case UPDATE_REP_REFS:
00109 status = svc->updateRepRefs(pAddress, pObject);
00110 break;
00111 default:
00112 status = StatusCode::FAILURE;
00113 break;
00114 }
00115 status.ignore();
00116 return status;
00117 }
00118 return StatusCode::SUCCESS;
00119 }
00120
00122 StatusCode PersistencySvc::createObj(IOpaqueAddress* pAddr, DataObject*& refpObj) {
00123 return makeCall(CREATE_OBJ, pAddr, refpObj);
00124 }
00125
00127 StatusCode PersistencySvc::fillObjRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
00128 return makeCall(FILL_OBJ_REFS, pAddr, pObj);
00129 }
00130
00132 StatusCode PersistencySvc::updateObj(IOpaqueAddress* pAddr, DataObject* pObj) {
00133 return makeCall(UPDATE_OBJ, pAddr, pObj);
00134 }
00135
00137 StatusCode PersistencySvc::updateObjRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
00138 return makeCall(UPDATE_OBJ_REFS, pAddr, pObj);
00139 }
00140
00142 StatusCode PersistencySvc::createRep(DataObject* pObj, IOpaqueAddress*& refpAddr) {
00143 return makeCall(CREATE_REP, refpAddr, pObj);
00144 }
00145
00147 StatusCode PersistencySvc::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
00148 return makeCall(FILL_REP_REFS, pAddr, pObj);
00149 }
00150
00152 StatusCode PersistencySvc::updateRep(IOpaqueAddress* pAddr, DataObject* pObj) {
00153 return makeCall(UPDATE_REP, pAddr, pObj);
00154 }
00155
00157 StatusCode PersistencySvc::updateRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) {
00158 return makeCall(UPDATE_REP_REFS, pAddr, pObj);
00159 }
00160
00162 SmartIF<IAddressCreator>& PersistencySvc::addressCreator(long type) {
00163 long typ = type;
00164 Services::iterator it = m_cnvServices.find( typ );
00165 if( it == m_cnvServices.end() ) {
00166 IConversionSvc* s = service(type);
00167 if ( s ) {
00168 it = m_cnvServices.find( typ );
00169 if ( it != m_cnvServices.end() ) {
00170 return (*it).second.addrCreator();
00171 }
00172 }
00173 static SmartIF<IAddressCreator> no_creator;
00174 return no_creator;
00175 }
00176 return (*it).second.addrCreator();
00177 }
00178
00180 StatusCode PersistencySvc::setDataProvider(IDataProviderSvc* pDataSvc) {
00181 m_dataSvc = pDataSvc;
00182 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00183 (*i).second.conversionSvc()->setDataProvider(m_dataSvc).ignore();
00184 }
00185 return StatusCode(StatusCode::SUCCESS,true);
00186 }
00187
00189 SmartIF<IDataProviderSvc>& PersistencySvc::dataProvider() const {
00190 return m_dataSvc;
00191 }
00192
00194 StatusCode PersistencySvc::setConversionSvc(IConversionSvc* svc) {
00195 m_cnvDefault = svc;
00196 return StatusCode(StatusCode::SUCCESS,true);
00197 }
00198
00200 SmartIF<IConversionSvc>& PersistencySvc::conversionSvc() const {
00201 return m_cnvDefault;
00202 }
00203
00205 StatusCode PersistencySvc::addConverter(const CLID& ) {
00206 return StatusCode::FAILURE;
00207 }
00208
00210 StatusCode PersistencySvc::addConverter(IConverter* pConverter) {
00211 if ( 0 != pConverter ) {
00212 long typ = pConverter->repSvcType();
00213 IConversionSvc* svc = service(typ);
00214 if ( 0 != svc ) {
00215 return svc->addConverter(pConverter);
00216 }
00217 return BAD_STORAGE_TYPE;
00218 }
00219 return NO_CONVERTER;
00220 }
00221
00223 StatusCode PersistencySvc::removeConverter(const CLID& clid) {
00224
00225 StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS;
00226 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00227 iret = (*i).second.conversionSvc()->removeConverter(clid);
00228 if ( iret.isSuccess() ) {
00229 status = iret;
00230 }
00231 }
00232 return status;
00233 }
00234
00236 IConverter* PersistencySvc::converter(const CLID& ) {
00237 return 0;
00238 }
00239
00241 SmartIF<IConversionSvc>& PersistencySvc::service(const std::string& nam) {
00242 Gaudi::Utils::TypeNameString tn(nam);
00243 IConversionSvc* svc = 0;
00244 for ( Services::iterator it = m_cnvServices.begin(); it != m_cnvServices.end(); it++ ) {
00245 if ( (*it).second.service()->name() == tn.name() ) {
00246 return (*it).second.conversionSvc();
00247 }
00248 }
00249 StatusCode status = Service::service(nam, svc, true);
00250 if ( status.isSuccess() ) {
00251 if ( addCnvService(svc).isSuccess() ) {
00252 svc->release();
00253 return service(nam);
00254 }
00255 }
00256 info() << "Cannot access Conversion service:" << nam << endmsg;
00257 static SmartIF<IConversionSvc> no_svc;
00258 return no_svc;
00259 }
00260
00262 SmartIF<IConversionSvc>& PersistencySvc::service(long type) {
00263 typedef std::vector<std::string> SvcNames;
00264
00265 Services::iterator it = m_cnvServices.find( type );
00266 if( it != m_cnvServices.end() ) {
00267 return (*it).second.conversionSvc();
00268 }
00269
00270 const SvcNames& theNames = m_svcNames.value();
00271 for ( SvcNames::const_iterator i = theNames.begin(); i != theNames.end(); i++ ) {
00272 SmartIF<IConversionSvc>& svc = service(*i);
00273 if ( svc != 0 ) {
00274 long typ = svc->repSvcType();
00275 if ( typ == type ) {
00276 return svc;
00277 }
00278 }
00279 }
00280 static SmartIF<IConversionSvc> no_svc;
00281 return no_svc;
00282 }
00283
00285 StatusCode PersistencySvc::addCnvService(IConversionSvc* servc) {
00286 if ( 0 != servc ) {
00287 long type = servc->repSvcType();
00288 long def_typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
00289 Services::iterator it = m_cnvServices.find( type );
00290 IConversionSvc* cnv_svc = 0;
00291 if ( it != m_cnvServices.end() ) {
00292 cnv_svc = (*it).second.conversionSvc();
00293 }
00294 if ( type == def_typ ) {
00295 m_cnvDefault = servc;
00296 }
00297 if ( cnv_svc != servc ) {
00298 IAddressCreator* icr = 0;
00299 StatusCode status = servc->queryInterface(IAddressCreator::interfaceID(), pp_cast<void>(&icr));
00300 if ( status.isSuccess() ) {
00301 IService* isvc = 0;
00302 status = servc->queryInterface(IService::interfaceID(), pp_cast<void>(&isvc));
00303 if ( status.isSuccess() ) {
00304 if ( 0 != cnv_svc ) {
00305 removeCnvService (type).ignore();
00306 }
00307 std::pair<Services::iterator, bool> p =
00308 m_cnvServices.insert( Services::value_type( type, ServiceEntry(type, isvc, servc, icr)));
00309 if( p.second ) {
00310 info() << "Added successfully Conversion service:" << isvc->name() << endmsg;
00311 servc->addRef();
00312 servc->setAddressCreator(this).ignore();
00313 servc->setDataProvider(m_dataSvc).ignore();
00314 return StatusCode::SUCCESS;
00315 }
00316 info() << "Cannot add Conversion service of type " << isvc->name() << endmsg;
00317 isvc->release();
00318 icr->release();
00319 return StatusCode::FAILURE;
00320 }
00321 icr->release();
00322 }
00323 info() << "Cannot add Conversion service of type " << type << endmsg;
00324 return StatusCode::FAILURE;
00325 }
00326 else {
00327 return StatusCode::SUCCESS;
00328 }
00329 }
00330 return BAD_STORAGE_TYPE;
00331 }
00332
00334 StatusCode PersistencySvc::removeCnvService(long svctype) {
00335 Services::iterator it = m_cnvServices.find( svctype );
00336 if( it != m_cnvServices.end() ) {
00337 (*it).second.service()->release();
00338 (*it).second.addrCreator()->release();
00339 m_cnvServices.erase(it);
00340 return StatusCode::SUCCESS;
00341 }
00342 return BAD_STORAGE_TYPE;
00343 }
00344
00346 long PersistencySvc::repSvcType() const {
00347 long typ = (m_cnvDefault) ? m_cnvDefault->repSvcType() : 0;
00348 return typ;
00349 }
00350
00352 StatusCode PersistencySvc::setDefaultCnvService(long type) {
00353 m_cnvDefault = service(type);
00354 return StatusCode::SUCCESS;
00355 }
00356
00358 StatusCode PersistencySvc::connectOutput(const std::string& outputFile,
00359 const std::string& ) {
00360 return connectOutput(outputFile);
00361 }
00362
00364 StatusCode PersistencySvc::connectOutput(const std::string&) {
00365 return StatusCode::SUCCESS;
00366 }
00367
00369 StatusCode PersistencySvc::commitOutput(const std::string& , bool ) {
00370 return StatusCode::SUCCESS;
00371 }
00372
00374 StatusCode PersistencySvc::createAddress(long svc_type,
00375 const CLID& clid,
00376 const std::string* pars,
00377 const unsigned long* ipars,
00378 IOpaqueAddress*& refpAddress) {
00379 IAddressCreator* svc = addressCreator(svc_type);
00380 StatusCode status = BAD_STORAGE_TYPE;
00381 refpAddress = 0;
00382 if ( 0 != svc ) {
00383 status = svc->createAddress(svc_type, clid, pars, ipars, refpAddress);
00384 }
00385 return status;
00386 }
00387
00389 StatusCode PersistencySvc::convertAddress( const IOpaqueAddress* pAddress,
00390 std::string& refAddress)
00391 {
00392
00393
00394
00395 long svc_type = 0;
00396 CLID clid = 0;
00397 if ( 0 != pAddress ) {
00398 svc_type = pAddress->svcType();
00399 clid = pAddress->clID();
00400 }
00401 IAddressCreator* svc = addressCreator(svc_type);
00402 StatusCode status = BAD_STORAGE_TYPE;
00403 refAddress = "";
00404
00405 if ( 0 != svc ) {
00406
00407 encodeAddrHdr(svc_type, clid, refAddress);
00408 std::string address;
00409
00410 status = svc->convertAddress(pAddress, address);
00411 refAddress += address;
00412 }
00413 return status;
00414 }
00415
00417 StatusCode PersistencySvc::createAddress( long ,
00418 const CLID& ,
00419 const std::string& refAddress,
00420 IOpaqueAddress*& refpAddress)
00421 {
00422
00423
00424
00425 long new_svc_type = 0;
00426 CLID new_clid = 0;
00427 std::string address_trailer;
00428 decodeAddrHdr(refAddress, new_svc_type, new_clid, address_trailer);
00429 IAddressCreator* svc = addressCreator(new_svc_type);
00430 StatusCode status = BAD_STORAGE_TYPE;
00431 if ( 0 != svc ) {
00432 status = svc->createAddress( new_svc_type, new_clid, address_trailer, refpAddress);
00433 }
00434 return status;
00435 }
00436
00438 void PersistencySvc::encodeAddrHdr( long service_type,
00439 const CLID& clid,
00440 std::string& address) const
00441 {
00442
00443
00444 std::stringstream stream;
00445 int svctyp = service_type;
00446 stream << "<address_header service_type=\"" << svctyp << "\" clid=\"" << clid << "\" /> ";
00447 address = stream.str();
00448 }
00449
00451 void PersistencySvc::decodeAddrHdr( const std::string& address,
00452 long& service_type,
00453 CLID& clid,
00454 std::string& address_trailer) const
00455 {
00456
00457
00458 service_type = 0;
00459 clid = 0;
00460 address_trailer = "";
00461
00462
00463 size_t pos = address.find("<address_header");
00464 if (std::string::npos != pos) {
00465
00466 pos = address.find("service_type=\"");
00467 if (std::string::npos != pos) {
00468 pos += 14;
00469 size_t end = address.find('"', pos);
00470 if (std::string::npos != end) {
00471 std::istringstream str(address.substr(pos, end-pos));
00472 str >> service_type;
00473
00474 pos = address.find("clid=\"");
00475 if (std::string::npos != pos) {
00476 pos += 6;
00477 end = address.find('\"', pos);
00478 if (std::string::npos != end) {
00479 str.clear();
00480 str.str(address.substr(pos, end-pos));
00481 str >> clid;
00482
00483 pos = address.find('>');
00484 if (pos < (address.size()-2)) {
00485
00486 address_trailer = address.substr(pos+1);
00487 }
00488 }
00489 }
00490 }
00491 }
00492 }
00493 }
00494
00496 StatusCode PersistencySvc::setAddressCreator(IAddressCreator*) {
00497
00498
00499
00500
00501 return StatusCode::FAILURE;
00502 }
00503
00505 SmartIF<IAddressCreator>& PersistencySvc::addressCreator() const {
00506 return m_addrCreator;
00507 }
00508
00510 StatusCode PersistencySvc::getService(long service_type, IConversionSvc*& refpSvc) {
00511 refpSvc = service(service_type);
00512 return (0==refpSvc) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00513 }
00514
00516 StatusCode PersistencySvc::getService(const std::string& service_type, IConversionSvc*& refpSvc) {
00517 const char* imp = service_type.c_str();
00518 long len = service_type.length();
00519 if ( ::strncasecmp(imp,"SICB", len) == 0 )
00520 return getService(SICB_StorageType, refpSvc);
00521 else if ( ::strncasecmp(imp,"ZEBRA", len) == 0 )
00522 return getService(SICB_StorageType, refpSvc);
00523 else if ( ::strncasecmp(imp,"MS Access", len) == 0 )
00524 return getService(ACCESS_StorageType, refpSvc);
00525 else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
00526 return getService(ACCESS_StorageType, refpSvc);
00527 else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
00528 return getService(SQLSERVER_StorageType, refpSvc);
00529 else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
00530 return getService(ORACLE_StorageType, refpSvc);
00531 else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
00532 return getService(ORACLE_StorageType, refpSvc);
00533 else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
00534 return getService(ORACLE_StorageType, refpSvc);
00535 else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
00536 return getService(MYSQL_StorageType, refpSvc);
00537 else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
00538 return getService(ROOT_StorageType, refpSvc);
00539 else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
00540 return getService(OBJY_StorageType, refpSvc);
00541 else if ( ::strncasecmp(imp,"OBJYECTI", 7) == 0 )
00542 return getService(OBJY_StorageType, refpSvc);
00543 else if ( ::strncasecmp(imp,"POOL_ROOTKEY", 12) == 0 )
00544 return getService(POOL_ROOTKEY_StorageType, refpSvc);
00545 else if ( ::strncasecmp(imp,"POOL_ROOTTREE", 12) == 0 )
00546 return getService(POOL_ROOTTREE_StorageType, refpSvc);
00547 else if ( ::strncasecmp(imp,"POOL_ROOT", 9) == 0 )
00548 return getService(POOL_ROOT_StorageType, refpSvc);
00549 else if ( ::strncasecmp(imp,"POOL_MySQL", 8) == 0 )
00550 return getService(POOL_MYSQL_StorageType, refpSvc);
00551 else if ( ::strncasecmp(imp,"POOL_ORACLE", 8) == 0 )
00552 return getService(POOL_ORACLE_StorageType, refpSvc);
00553 else if ( ::strncasecmp(imp,"POOL_ACCESS", 8) == 0 )
00554 return getService(POOL_ACCESS_StorageType, refpSvc);
00555 else if ( ::strncasecmp(imp,"POOL", 4) == 0 )
00556 return getService(POOL_StorageType, refpSvc);
00557
00558 for(Services::const_iterator i=m_cnvServices.begin(); i != m_cnvServices.end();++i) {
00559 SmartIF<IService> svc((*i).second.conversionSvc());
00560 if ( svc ) {
00561
00562 if ( svc->name() == service_type ) {
00563 refpSvc = (*i).second.conversionSvc();
00564 return StatusCode::SUCCESS;
00565 }
00566
00567 if ( System::typeinfoName(typeid(*(svc.get()))) == service_type ) {
00568 refpSvc = (*i).second.conversionSvc();
00569 return StatusCode::SUCCESS;
00570 }
00571 }
00572 }
00573 const std::vector<std::string>& names = m_svcNames;
00574
00575 for(std::vector<std::string>::const_iterator i=names.begin(); i != names.end(); i++) {
00576 Gaudi::Utils::TypeNameString itm(*i);
00577 if ( itm.name() == service_type || itm.type() == service_type ) {
00578 IConversionSvc* svc = service(*i);
00579 if ( svc ) {
00580 refpSvc = svc;
00581 return StatusCode::SUCCESS;
00582 }
00583 }
00584 }
00585 return StatusCode::FAILURE;
00586 }
00587
00589 const CLID& PersistencySvc::objType() const {
00590 return CLID_NULL;
00591 }
00592
00594 StatusCode PersistencySvc::initialize() {
00595 m_addrCreator = this;
00596
00597 StatusCode status = Service::initialize();
00598 if ( UNLIKELY(!status.isSuccess()) ) {
00599 error() << "Error initializing Service base class." << endmsg;
00600 }
00601 return status;
00602 }
00603
00605 StatusCode PersistencySvc::finalize() {
00606
00607 m_cnvServices.clear();
00608
00609 m_addrCreator = 0;
00610 return StatusCode::SUCCESS;
00611 }
00612
00613 void PersistencySvc::svcNamesHandler( Property& p ) {
00614 DEBMSG << p << endmsg;
00615 }
00616
00618 bool PersistencySvc::enable(bool value)
00619 {
00620 bool old = m_enable;
00621 m_enable = value;
00622 return old;
00623 }
00624
00626 PersistencySvc::PersistencySvc(const std::string& name, ISvcLocator* svc)
00627 : base_class(name, svc),
00628 m_cnvDefType(TEST_StorageType),
00629 m_enable(true)
00630 {
00631 declareProperty("CnvServices", m_svcNames);
00632 m_svcNames.declareUpdateHandler( &PersistencySvc::svcNamesHandler, this );
00633 }
00634
00636 PersistencySvc::~PersistencySvc() {
00637 }