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