00001 #include "DybStorageSvc.h"
00002
00003 #include "Event/RegistrationSequence.h"
00004 #include "PerBaseEvent/PerRegistrationSequence.h"
00005 #include "RootIOSvc/RootIOAddress.h"
00006 #include "RootIOSvc/RootIOBaseCnv.h"
00007
00008 #include "GaudiKernel/MsgStream.h"
00009 #include "GaudiKernel/AlgTool.h"
00010 #include "GaudiKernel/IConversionSvc.h"
00011
00012 #include <map>
00013 #include <string>
00014
00015 using namespace DayaBay;
00016 using namespace std;
00017
00018 DybStorageSvc::DybStorageSvc(const std::string& name, ISvcLocator* svc)
00019 : Service(name,svc)
00020 , m_cnv(0)
00021 {
00022 declareProperty("RegSeqVisitors", m_rsVisitors,
00023 "List IRegSeqVisitors" );
00024 }
00025
00026 DybStorageSvc::~DybStorageSvc()
00027 {
00028 }
00029
00030 StatusCode DybStorageSvc::initialize()
00031 {
00032 StatusCode sc = Service::initialize();
00033 if (sc.isFailure()) return sc;
00034
00035 MsgStream log(msgSvc(), "DybStorageSvc");
00036
00037 sc = serviceLocator()->getService("RootIOCnvSvc",
00038 IID_IConversionSvc,
00039 *pp_cast<IInterface>(&m_cnv));
00040 if (sc.isFailure()) {
00041 log << MSG::ERROR
00042 << "Failed to get IConversionSvc RootIOCnvSvc" << endreq;
00043 return sc;
00044 }
00045
00046 sc = m_rsVisitors.retrieve();
00047 if (sc.isFailure()) {
00048 log << MSG::ERROR
00049 << "Failed to retrieve IRegSeqVisitors" << endreq;
00050 return sc;
00051 }
00052
00053
00054 ToolHandleArray<IRegSeqVisitor>::iterator it, done = m_rsVisitors.end();
00055 for (it = m_rsVisitors.begin(); it != done; ++it) {
00056 AlgTool* tool = dynamic_cast<AlgTool*>(&**it);
00057 if (tool) {
00058 log << MSG::INFO << "Got RegSeqVisitor: " << tool->name() << endreq;
00059 }
00060 }
00061
00062 return StatusCode::SUCCESS;
00063 }
00064
00065 StatusCode DybStorageSvc::finalize()
00066 {
00067 return StatusCode::SUCCESS;
00068 }
00069
00070 StatusCode DybStorageSvc::store(const IRegistrationSequence& iregSeq)
00071 {
00072 MsgStream log(msgSvc(), "DybStorageSvc");
00073
00074 RegistrationSequence* regSeq =
00075 const_cast<RegistrationSequence*>(
00076 dynamic_cast<const RegistrationSequence*>(&iregSeq));
00077
00078 if (!regSeq) {
00079 log << MSG::ERROR
00080 << "given an IRegistrationSequence that "
00081 << "is not a RegistrationSequence"
00082 << endreq;
00083 return StatusCode::FAILURE;
00084 }
00085
00086
00087 {
00088 ToolHandleArray<IRegSeqVisitor>::iterator it, done = m_rsVisitors.end();
00089 for (it = m_rsVisitors.begin(); it != done; ++it) {
00090 {
00091 AlgTool* tool = dynamic_cast<AlgTool*>(&**it);
00092 if (tool) {
00093 log << MSG::DEBUG << "Calling RegSeqVisitor: " << tool->name() << endreq;
00094 }
00095 }
00096 StatusCode sc = (*it)->visit(*regSeq);
00097 if (sc.isFailure()) {
00098 log << MSG::ERROR
00099 << "RegistartionSequence visitor failed" << endreq;
00100 return sc;
00101 }
00102 }
00103 }
00104
00105
00106
00107 IOpaqueAddress* regSeq_addr = 0;
00108
00109 {
00110 StatusCode sc = m_cnv->createRep(regSeq,regSeq_addr);
00111 if (sc.isFailure()) {
00112 log << MSG::ERROR
00113 << "failed to create persistent representation "
00114 << "for the RegistrationSequence"
00115 << endreq;
00116 return sc;
00117 }
00118 }
00119
00120
00121
00122 IRegistrationSequence::Registrations& regs =
00123 const_cast<IRegistrationSequence::Registrations&>(regSeq->registrations());
00124 IRegistrationSequence::Registrations::iterator it, done = regs.end();
00125
00126
00127 for (it = regs.begin(); it != done; ++it) {
00128 {
00129 ObjectReg& objreg = *it;
00130 if (!objreg.store()) {
00131 log << MSG::DEBUG << "Not storing " << objreg.path() << endreq;
00132 continue;
00133 }
00134
00135 DataObject* child = const_cast<DataObject*>(objreg.object());
00136
00137 IOpaqueAddress* addr = 0;
00138 StatusCode sc = m_cnv->createRep(child,addr);
00139
00140 if (sc.isFailure()) {
00141 log << MSG::WARNING
00142 << "Failed to createRep for "
00143 << objreg.path() << ", skipping" << endreq;
00144 continue;
00145 }
00146 IRegistry* reg = child->registry();
00147 reg->setAddress(addr);
00148 }
00149 {
00150 const ObjectReg& objreg = *it;
00151 if (!objreg.store()) { continue; }
00152
00153 DataObject* child = const_cast<DataObject*>(objreg.object());
00154
00155 IRegistry* reg = child->registry();
00156 StatusCode sc = m_cnv->fillRepRefs(reg->address(), child);
00157 if (sc.isFailure()) {
00158 log << MSG::WARNING
00159 << "Failed to fillRepRefs with "
00160 << objreg.path() << ", skipping" << endreq;
00161 continue;
00162 }
00163 IOpaqueAddress* iaddr = reg->address();
00164 if (!iaddr) {
00165 static map<string,int> errorMap;
00166 string tespath = objreg.path();
00167 if (!errorMap[tespath]) {
00168 log << (child->clID() == 1 ? MSG::DEBUG : MSG::WARNING)
00169 << "No address for object id #"<<child->clID()<<" registered at "
00170 << tespath << ", skipping and won't tell you about it again."
00171 << endreq;
00172 errorMap[tespath] = 1;
00173 }
00174 continue;
00175 }
00176 RootOutputAddress* roa = dynamic_cast<RootOutputAddress*>(iaddr);
00177 if (!roa) {
00178 log << MSG::ERROR
00179 << "Address for" << objreg.path()
00180 << " not a RootOutputAddress, skipping" << endreq;
00181 continue;
00182 }
00183 RootIOBaseCnv* rbcnv =
00184 dynamic_cast<RootIOBaseCnv*>(m_cnv->converter(child->clID()));
00185 if (!rbcnv) {
00186 log << MSG::ERROR
00187 << "No converter for type " << roa->clID()
00188 << " from " << objreg.path() << ", skipping" << endreq;
00189 continue;
00190 }
00191
00192 int entry = rbcnv->commit(*roa);
00193 roa->setEntry(entry);
00194
00195
00196 TemporalDataObject* tdo = dynamic_cast<TemporalDataObject*>(child);
00197 tdo->setOutputAddress(roa);
00198
00199 log << MSG::DEBUG
00200 << "Setting entry [" << entry << "] to " << objreg.path() << endreq;
00201 const_cast<ObjectReg&>(objreg).setEntry(entry);
00202 }
00203 }
00204
00205 {
00206 StatusCode sc = m_cnv->fillRepRefs(regSeq_addr,regSeq);
00207 if (sc.isFailure()) {
00208 log << MSG::ERROR
00209 << "failed to fillRepRefs with RegistrationSequence"
00210 << endreq;
00211 return sc;
00212 }
00213 RootOutputAddress* roa =
00214 dynamic_cast<RootOutputAddress*>(regSeq_addr);
00215 if (!roa) {
00216 log << MSG::ERROR
00217 << "Failed to find a RootOutputAddress for RegistrationSequence!\n"
00218 << "\tDid you fail to tell me a file in which to save it?"
00219 << endreq;
00220 return StatusCode::FAILURE;
00221 }
00222 RootIOBaseCnv* rbcnv =
00223 dynamic_cast<RootIOBaseCnv*>(m_cnv->converter(roa->clID()));
00224 int entry = rbcnv->commit(*roa);
00225 roa->setEntry(entry);
00226
00227
00228 regSeq->setOutputAddress(roa);
00229 }
00230
00231 return StatusCode::SUCCESS;
00232 }
00233
00234 StatusCode DybStorageSvc::store(DataObject* object, const std::string& path)
00235 {
00236
00237 MsgStream log(msgSvc(), "DybStorageSvc");
00238
00239 IOpaqueAddress* addr = 0;
00240 log << MSG::VERBOSE << "Calling createRep for path " << path
00241 << " with object " << object << endreq;
00242 StatusCode sc = m_cnv->createRep(object,addr);
00243 log << MSG::VERBOSE << "Called createRep for path " << path
00244 << "and got addr " << addr << endreq;
00245 if (sc.isFailure()) {
00246 log << MSG::WARNING
00247 << "Failed to createRep for "
00248 << path << ", skipping" << endreq;
00249 return sc;
00250 }
00251 IRegistry* reg = object->registry();
00252 reg->setAddress(addr);
00253
00254 sc = m_cnv->fillRepRefs(reg->address(), object);
00255 if (sc.isFailure()) {
00256 log << MSG::WARNING
00257 << "Failed to fillRepRefs with "
00258 << path << ", skipping" << endreq;
00259 return sc;
00260 }
00261
00262 if (!addr) {
00263 log << (object->clID() == 1 ? MSG::VERBOSE : MSG::WARNING)
00264 << "No address for object id #"<<object->clID()<<" registered at "
00265 << path << ", skipping"
00266 << endreq;
00267 return sc;
00268 }
00269 RootOutputAddress* roa = dynamic_cast<RootOutputAddress*>(addr);
00270 if (!roa) {
00271 log << MSG::ERROR
00272 << "Address for" << path
00273 << " not a RootOutputAddress, skipping" << endreq;
00274 return sc;
00275 }
00276 RootIOBaseCnv* rbcnv =
00277 dynamic_cast<RootIOBaseCnv*>(m_cnv->converter(object->clID()));
00278 if (!rbcnv) {
00279 log << MSG::ERROR
00280 << "No converter for type " << roa->clID()
00281 << " from " << path << ", skipping" << endreq;
00282 return sc;
00283 }
00284
00285 int entry = rbcnv->commit(*roa);
00286 roa->setEntry(entry);
00287
00288 log << MSG::DEBUG
00289 << "Setting entry [" << entry << "] to " << path << endreq;
00290
00291 return StatusCode::SUCCESS;
00292 }
00293
00294
00295
00296 StatusCode DybStorageSvc::queryInterface(const InterfaceID& riid,
00297 void** ppvInterface)
00298 {
00299 MsgStream log(msgSvc(), "DybStorageSvc::queryInterface");
00300 log << MSG::DEBUG << "queryInterface(" << riid << ")" << endreq;
00301
00302 StatusCode sc = StatusCode::FAILURE;
00303 if (ppvInterface) {
00304 *ppvInterface = 0;
00305
00306 if (IDybStorageSvc::interfaceID().versionMatch(riid)) {
00307 *ppvInterface = static_cast<IDybStorageSvc*>(this);
00308 sc = StatusCode::SUCCESS;
00309 addRef();
00310 }
00311 else sc = Service::queryInterface( riid, ppvInterface );
00312 }
00313 return sc;
00314 }