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/GenericLink.h"
00026 #include "GaudiKernel/IConverter.h"
00027 #include "GaudiKernel/ISvcLocator.h"
00028 #include "GaudiKernel/IDataSelector.h"
00029 #include "GaudiKernel/IOpaqueAddress.h"
00030 #include "GaudiKernel/IDataProviderSvc.h"
00031 #include "GaudiKernel/MsgStream.h"
00032
00033 #ifdef WIN32
00034 # define strncasecmp _strnicmp
00035 #else
00036 # include <strings.h>
00037 #endif
00038
00039
00040 #include "PersistencySvc.h"
00041
00042
00043
00044 static const SvcFactory<PersistencySvc> s_factory;
00045 const ISvcFactory& PersistencySvcFactory = s_factory;
00046
00048 StatusCode PersistencySvc::initialize() {
00049
00050 StatusCode status = Service::initialize();
00051 MsgStream log( msgSvc(), name() );
00052 if ( status.isFailure() ) {
00053 log << MSG::ERROR << "Error initializing Service base class." << endreq;
00054 return status;
00055 }
00056 status = setProperties();
00057 if ( status.isFailure() ) {
00058 log << MSG::ERROR << "Error retrieving properties." << endreq;
00059 return status;
00060 }
00061
00062 status = decodeSvcNames( );
00063 return status;
00064 }
00065
00067 StatusCode PersistencySvc::finalize() {
00068 m_knownSvc.erase(m_knownSvc.begin(), m_knownSvc.end());
00069 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00070 (*i).second.service()->release();
00071 }
00072 return StatusCode::SUCCESS;
00073 }
00074
00076 StatusCode PersistencySvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) {
00077 unsigned char svc_type = pAddress->svcType();
00078 IConversionSvc* svc = service(svc_type);
00079 StatusCode status = BAD_STORAGE_TYPE;
00080 if ( 0 != svc ) {
00081 status = svc->createObj(pAddress, refpObject);
00082 return status;
00083 }
00084 refpObject = 0;
00085
00086 return status;
00087 }
00088
00090 StatusCode PersistencySvc::updateObj(IOpaqueAddress* pAddress, DataObject* pObject) {
00091 unsigned char svc_type = pAddress->svcType();
00092 IConversionSvc* svc = service(svc_type);
00093 StatusCode status = BAD_STORAGE_TYPE;
00094 if ( 0 != svc ) {
00095 status = svc->updateObj(pAddress, pObject);
00096 return status;
00097 }
00098 pObject = 0;
00099
00100 return status;
00101 }
00102
00104 StatusCode PersistencySvc::updateReps(IDataSelector* pSelector) {
00105 StatusCode status = SUCCESS, iret = SUCCESS;
00106
00107
00108
00109 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00110
00111 iret = (*i).second.service()->updateReps(pSelector);
00112 if ( iret.isSuccess() ) {
00113 status = iret;
00114 }
00115 }
00116 return iret;
00117 }
00118
00120 StatusCode PersistencySvc::createReps(IDataSelector* pSelector) {
00121 StatusCode status = NO_CONVERTER;
00122
00123 if ( 0 != m_cnvDefault ) {
00124 status = m_cnvDefault->createReps(pSelector);
00125 }
00126 return status;
00127 }
00128
00130 IConversionSvc* PersistencySvc::service(unsigned char type) {
00131 Services::iterator it = m_cnvServices.find( type );
00132 if( it != m_cnvServices.end() ) {
00133 return (*it).second.service();
00134 }
00135 for ( std::vector<IConversionSvc*>::iterator ik=m_knownSvc.begin(); ik != m_knownSvc.end(); ik++ ) {
00136 IConversionSvc* cnvSvc = (*ik);
00137 unsigned char svcTyp = cnvSvc->repSvcType();
00138 if ( type == svcTyp ) {
00139 StatusCode iret = addCnvService( cnvSvc );
00140 if ( !iret.isSuccess() ) {
00141 MsgStream log( msgSvc(), name() );
00142 SmartIF<IService> sif(IID_IService, cnvSvc);
00143 if ( sif.isValid( ) ) {
00144 log << MSG::ERROR << "Cannot use Conversion service:" << sif->name() << endreq;
00145 }
00146 else {
00147 log << MSG::ERROR << "Cannot use Conversion service: Bad interface" << endreq;
00148 }
00149 }
00150 else {
00151 m_knownSvc.erase(ik);
00152 return cnvSvc;
00153 }
00154 }
00155 }
00156 return 0;
00157 }
00158
00160 IAddressCreator* PersistencySvc::addressCreator(unsigned char type) {
00161 Services::iterator it = m_cnvServices.find( type );
00162 if( it == m_cnvServices.end() ) {
00163 IConversionSvc* s = service(type);
00164 if ( s ) {
00165 it = m_cnvServices.find( type );
00166 if ( it != m_cnvServices.end() ) {
00167 return (*it).second.addrCreator();
00168 }
00169 }
00170 return 0;
00171 }
00172 return (*it).second.addrCreator();
00173 }
00174
00176 StatusCode PersistencySvc::setStore(IDataProviderSvc* pDataSvc) {
00177 m_dataSvc = pDataSvc;
00178 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00179 (*i).second.service()->setStore(m_dataSvc);
00180 }
00181 return StatusCode::SUCCESS;
00182 }
00183
00185 StatusCode PersistencySvc::addConverter(IConverter* pConverter) {
00186 unsigned char typ = pConverter->repSvcType();
00187 IConversionSvc* svc = service(typ);
00188 StatusCode status = BAD_STORAGE_TYPE;
00189 if ( 0 != svc ) {
00190 status = svc->addConverter(pConverter);
00191 }
00192 return status;
00193 }
00194
00196 StatusCode PersistencySvc::addConverter(const ICnvFactory& refFactory) {
00197 StatusCode status = NO_CONVERTER;
00198 IConverter* pConverter = refFactory.instantiate(serviceLocator());
00199 if ( 0 != pConverter ) {
00200 unsigned char typ = pConverter->repSvcType();
00201 IConversionSvc* svc = service(typ);
00202 status = BAD_STORAGE_TYPE;
00203 if ( 0 != svc ) {
00204 status = svc->addConverter(pConverter);
00205 }
00206 }
00207 return status;
00208 }
00209
00211 StatusCode PersistencySvc::removeConverter(const CLID& clid) {
00212
00213 StatusCode status = NO_CONVERTER, iret = StatusCode::SUCCESS;
00214 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00215 iret = (*i).second.service()->removeConverter(clid);
00216 if ( iret.isSuccess() ) {
00217 status = iret;
00218 }
00219 }
00220 return status;
00221 }
00222
00224 StatusCode PersistencySvc::addCnvService(IConversionSvc* servc) {
00225 if ( 0 != servc ) {
00226 IAddressCreator* icr = 0;
00227 StatusCode status = servc->queryInterface(IID_IAddressCreator, (void**)&icr);
00228 unsigned char type = servc->repSvcType();
00229 if ( status.isSuccess() ) {
00230 Services::iterator it = m_cnvServices.find( type );
00231 IConversionSvc* cnv_svc = 0;
00232 if ( it != m_cnvServices.end() ) {
00233 cnv_svc = (*it).second.service();
00234 }
00235 if ( cnv_svc != servc ) {
00236 if ( 0 != cnv_svc ) {
00237 removeCnvService (type);
00238 }
00239 std::pair<Services::iterator, bool> p =
00240 m_cnvServices.insert( Services::value_type( type, ServiceEntry(type, servc, icr)));
00241 if( p.second == false) {
00242 return StatusCode::FAILURE;
00243 }
00244 servc->addRef();
00245 }
00246 if ( type == m_cnvDefType ) {
00247 m_cnvDefault = servc;
00248 }
00249 servc->setAddressCreator(this);
00250 return StatusCode::SUCCESS;
00251 }
00252 }
00253 return BAD_STORAGE_TYPE;
00254 }
00255
00257 StatusCode PersistencySvc::removeCnvService(unsigned char svctype) {
00258 Services::iterator it = m_cnvServices.find( svctype );
00259 if( it != m_cnvServices.end() ) {
00260 (*it).second.service()->release();
00261 m_cnvServices.erase(it);
00262 return StatusCode::SUCCESS;
00263 }
00264 return BAD_STORAGE_TYPE;
00265 }
00266
00268 unsigned char PersistencySvc::repSvcType() const {
00269 return m_cnvDefault->repSvcType();
00270 }
00271
00273 StatusCode PersistencySvc::setDefaultCnvService(unsigned char type) {
00274 m_cnvDefault = service(type);
00275 return StatusCode::SUCCESS;
00276 }
00277
00279 StatusCode PersistencySvc::connectOutput(const std::string&) {
00280 return StatusCode::SUCCESS;
00281 }
00282
00284 StatusCode PersistencySvc::createAddress(const GenericLinkBase& link,
00285 const std::string& dbName,
00286 const std::string& contName,
00287 const std::string& objName,
00288 IOpaqueAddress*& refpAddress) {
00289 IAddressCreator* svc = addressCreator(link.svcType());
00290 StatusCode status = BAD_STORAGE_TYPE;
00291 refpAddress = 0;
00292 if ( 0 != svc ) {
00293 status = svc->createAddress(link, dbName, contName, objName, refpAddress);
00294 }
00295 return status;
00296 }
00297
00299 StatusCode PersistencySvc::createAddress(unsigned char type,
00300 const CLID& classId,
00301 const std::string& dbName,
00302 const std::string& contName,
00303 int seqId,
00304 IOpaqueAddress*& refpAddress) {
00305 IAddressCreator* svc = addressCreator(type);
00306 StatusCode status = BAD_STORAGE_TYPE;
00307 refpAddress = 0;
00308 if ( 0 != svc ) {
00309 status = svc->createAddress(type, classId, dbName, contName, seqId, refpAddress);
00310 }
00311 return status;
00312 }
00313
00315 StatusCode PersistencySvc::setAddressCreator(IAddressCreator*) {
00316
00317
00318
00319
00320 return StatusCode::FAILURE;
00321 }
00322
00324 StatusCode PersistencySvc::getService(unsigned char service_type, IConversionSvc*& refpSvc) {
00325 refpSvc = service(service_type);
00326 return (0==refpSvc) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00327 }
00328
00330 StatusCode PersistencySvc::getService(const std::string& service_type, IConversionSvc*& refpSvc) {
00331 const char* imp = service_type.c_str();
00332 long len = strlen(imp);
00333 if ( ::strncasecmp(imp,"SICB", len) == 0 )
00334 return getService(SICB_StorageType, refpSvc);
00335 else if ( ::strncasecmp(imp,"ZEBRA", len) == 0 )
00336 return getService(SICB_StorageType, refpSvc);
00337 else if ( ::strncasecmp(imp,"MS Access", len) == 0 )
00338 return getService(ACCESS_StorageType, refpSvc);
00339 else if ( ::strncasecmp(imp,"Microsoft Access", strlen("Microsoft Access")) == 0 )
00340 return getService(ACCESS_StorageType, refpSvc);
00341 else if ( ::strncasecmp(imp,"SQL Server", len) == 0 )
00342 return getService(SQLSERVER_StorageType, refpSvc);
00343 else if ( ::strncasecmp(imp,"Microsoft ODBC for Oracle", len) == 0 )
00344 return getService(ORACLE_StorageType, refpSvc);
00345 else if ( ::strncasecmp(imp,"Oracle ODBC", strlen("Oracle ODBC")) == 0 )
00346 return getService(ORACLE_StorageType, refpSvc);
00347 else if ( ::strncasecmp(imp,"Oracle OCI", strlen("Oracle OCI")) == 0 )
00348 return getService(ORACLE_StorageType, refpSvc);
00349 else if ( ::strncasecmp(imp,"MySQL", len) == 0 )
00350 return getService(MYSQL_StorageType, refpSvc);
00351 else if ( ::strncasecmp(imp,"ROOT", len) == 0 )
00352 return getService(ROOT_StorageType, refpSvc);
00353 else if ( ::strncasecmp(imp,"OBJY", len) == 0 )
00354 return getService(OBJY_StorageType, refpSvc);
00355 else if ( ::strncasecmp(imp,"OBJYECTI", 7) == 0 )
00356 return getService(OBJY_StorageType, refpSvc);
00357 return StatusCode::FAILURE;
00358 }
00359
00361 StatusCode PersistencySvc::queryInterface(const IID& riid, void** ppvInterface) {
00362 if ( IID_IConversionSvc == riid ) {
00363 *ppvInterface = (IConversionSvc*)this;
00364 }
00365 else if ( IID_IPersistencySvc == riid ) {
00366 *ppvInterface = (IPersistencySvc*)this;
00367 }
00368 else if ( IID_IAddressCreator == riid ) {
00369 *ppvInterface = (IAddressCreator*)this;
00370 }
00371 else {
00372
00373 return Service::queryInterface(riid, ppvInterface);
00374 }
00375 addRef();
00376 return StatusCode::SUCCESS;
00377 }
00378
00379 StatusCode PersistencySvc::decodeSvcNames( )
00380 {
00381 StatusCode result = StatusCode::SUCCESS;
00382 if ( state( ) == INITIALIZED ) {
00383 MsgStream log( msgSvc(), name() );
00384 const std::vector<std::string>& theNames = m_svcNames.value( );
00385 for ( std::vector<std::string>::const_iterator i = theNames.begin(); i != theNames.end(); i++ ) {
00386 IConversionSvc* svc = 0;
00387 StatusCode iret = serviceLocator()->getService(*i, IID_IConversionSvc,(IInterface*&)svc);
00388 if ( iret.isSuccess() ) {
00389 m_knownSvc.push_back(svc);
00390 log << MSG::INFO << "Added successfully Conversion service:" << *i << endreq;
00391 }
00392 else {
00393 log << MSG::INFO << "Cannot add Conversion service:" << *i << " (Bad Interface)" << endreq;
00394 }
00395 }
00396 }
00397 return result;
00398 }
00399
00400 void PersistencySvc::svcNamesHandler( Property& )
00401 {
00402 decodeSvcNames( );
00403 }
00404
00406 PersistencySvc::PersistencySvc(const std::string& name, ISvcLocator* svc)
00407 : Service(name, svc),
00408 m_cnvDefType(TEST_StorageType),
00409 m_dataSvc(0),
00410 m_cnvDefault(0)
00411 {
00412 declareProperty("CnvServices", m_svcNames);
00413 m_svcNames.declareUpdateHandler( &PersistencySvc::svcNamesHandler, this );
00414 }
00415
00417 PersistencySvc::~PersistencySvc() {
00418
00419 for ( Services::iterator i = m_cnvServices.begin(); i != m_cnvServices.end(); i++ ) {
00420 (*i).second.service()->release();
00421 }
00422 m_cnvServices.erase(m_cnvServices.begin(), m_cnvServices.end());
00423 m_knownSvc.erase(m_knownSvc.begin(), m_knownSvc.end());
00424 }