Gaudi Framework, version v23r6

Home   Generated: Wed Jan 30 2013
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DataSvc.cpp
Go to the documentation of this file.
1 //====================================================================
2 // DataSvc.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : System ( The LHCb Offline System)
6 //
7 // Description: implementation of the Transient data service: DataSvc
8 //
9 // Author : M.Frank
10 // History :
11 // +---------+----------------------------------------------+---------
12 // | Date | Comment | Who
13 // +---------+----------------------------------------------+---------
14 // | 29/10/98| Initial version | M.Frank
15 // | 20/2/99 | Automatic data preloading introduced. | M.Frank
16 // +---------+----------------------------------------------+---------
17 //
18 //====================================================================
19 #define DATASVC_DATASVC_CPP
20 
21 // Framework include files
22 #include "GaudiKernel/IConverter.h"
25 
26 #include "GaudiKernel/xtoa.h"
27 #include "GaudiKernel/SvcFactory.h"
28 #include "GaudiKernel/DataObject.h"
30 
32 #include "GaudiKernel/DataSvc.h"
35 
36 // Include files
37 #include <cassert>
38 #include <cstdlib>
39 #include <vector>
40 #include <algorithm>
41 #include <sstream>
42 
43 namespace {
46  inline std::string itemToPath(int item) {
48  path << '/' << item;
49  return path.str();
50  }
51 }
52 
53 // If you absolutely need optimization: switch off dynamic_cast.
54 // This improves access to the data store roughly by 10 %
55 // for balanced trees.
56 //
57 // M.Frank
58 #define CAST_REGENTRY(x,y) dynamic_cast<x>(y)
59 //#define CAST_REGENTRY(x,y) (x)(y)
61 
62 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
63 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
64 
65 #define DEBMSG ON_DEBUG debug()
66 #define VERMSG ON_VERBOSE verbose()
67 
72  DataObject* pObject = 0;
73  StatusCode status = findObject(sub_tree_path, pObject);
74  if ( status.isSuccess() ) {
75  RegEntry* node_entry = CAST_REGENTRY(RegEntry*,pObject->registry());
76  if ( 0 != node_entry ) {
77  RegEntry* parent = node_entry->parentEntry();
78  if ( 0 != parent ) {
79  parent->remove(node_entry);
80  return StatusCode::SUCCESS;
81  }
82  return INVALID_PARENT;
83  }
84  return INVALID_OBJECT;
85  }
86  return status;
87 }
88 
93  if ( checkRoot() ) {
94  RegEntry* entry = CAST_REGENTRY(RegEntry*,pObject->registry());
95  if ( 0 != entry ) {
96  RegEntry* parent = entry->parentEntry();
97  if ( 0 != parent ) {
98  parent->remove(entry);
99  return SUCCESS;
100  }
101  return INVALID_PARENT;
102  }
103  return INVALID_OBJECT;
104  }
105  return INVALID_ROOT;
106 }
107 
110  if ( checkRoot() ) {
111  m_root->release();
112  m_root = 0;
113  return SUCCESS;
114  }
115  return INVALID_ROOT;
116 }
117 
122  IDataStoreAgent* pAgent) {
123  DataObject* pO = 0;
124  StatusCode status = findObject(sub_tree_path, pO);
125  if ( status.isSuccess() ) {
126  status = traverseSubTree(pO, pAgent);
127  }
128  return status;
129 }
130 
133  IDataStoreAgent* pAgent ) {
134  if ( checkRoot() ) {
135  RegEntry* entry = CAST_REGENTRY(RegEntry*,pObject->registry());
136  if ( 0 != entry ) {
137  return entry->traverseTree(pAgent);
138  }
139  return INVALID_OBJECT;
140  }
141  return INVALID_ROOT;
142 }
143 
146  if ( checkRoot() ) {
147  return m_root->traverseTree(pAgent);
148  }
149  return INVALID_ROOT;
150 }
151 
157  DataObject* pRootObj) {
158  clearStore().ignore();
159  return i_setRoot (root_path, pRootObj);
160 }
161 
168  DataObject* pRootObj) {
169  if ( 0 != pRootObj ) {
170  m_root = new RegEntry(root_path);
171  m_root->makeHard(pRootObj);
172  m_root->setDataSvc(this);
173  preLoad().ignore();
174  }
175  return SUCCESS;
176 }
177 
183  IOpaqueAddress* pRootAddr) {
184  clearStore().ignore();
185  return i_setRoot (root_path, pRootAddr);
186 }
187 
194  IOpaqueAddress* pRootAddr) {
195  if ( 0 != pRootAddr ) {
196  m_root = new RegEntry(root_path);
197  m_root->makeHard(pRootAddr);
198  m_root->setDataSvc(this);
199  preLoad().ignore();
200  }
201  return SUCCESS;
202 }
203 
206  if ( 0 != pDataLoader ) pDataLoader->addRef();
207  if ( 0 != m_dataLoader ) m_dataLoader->release();
208  if ( 0 != pDataLoader ) {
209  pDataLoader->setDataProvider(this).ignore();
210  }
211  m_dataLoader = pDataLoader;
212  return SUCCESS;
213 }
214 
217  IRegistry*& refpParent) {
218  if ( pObject ) {
219  return objectParent(pObject->registry(), refpParent);
220  }
221  return INVALID_OBJECT;
222 }
225  IRegistry*& refpParent) {
226  if ( checkRoot() ) {
227  const RegEntry* node_entry = CAST_REGENTRY(const RegEntry*,pRegistry);
228  if ( node_entry ) {
229  refpParent = node_entry->parent();
230  return StatusCode::SUCCESS;
231  }
232  return INVALID_OBJECT;
233  }
234  return INVALID_ROOT;
235 }
236 
239  std::vector<IRegistry*>& leaves) {
240  if ( pObject ) {
241  return objectLeaves(pObject->registry(), leaves);
242  }
243  return INVALID_OBJECT;
244 }
245 
250  std::vector<IRegistry*>& leaves) {
251  if ( checkRoot() ) {
252  const RegEntry* node_entry = CAST_REGENTRY(const RegEntry*,pRegistry);
253  if ( node_entry ) {
254  leaves = node_entry->leaves();
255  return StatusCode::SUCCESS;
256  }
257  return INVALID_OBJECT;
258  }
259  return INVALID_ROOT;
260 }
261 
264  IOpaqueAddress* pAddress) {
265  if ( fullPath.length() > 0 ) {
266  if ( fullPath[0] != SEPARATOR ) {
267  return registerAddress(m_root, fullPath, pAddress);
268  }
269  IRegistry* pRegistry = 0;
270  return registerAddress(pRegistry, fullPath, pAddress);
271  }
272  return INVALID_OBJ_PATH;
273 }
274 
277  const std::string& objectPath,
278  IOpaqueAddress* pAddress) {
279  IRegistry* pRegistry = (0 == parentObj) ? 0 : parentObj->registry();
280  return registerAddress(pRegistry, objectPath, pAddress);
281 }
282 
285  const std::string& objPath,
286  IOpaqueAddress* pAddress) {
287  if ( checkRoot() ) {
288  if ( objPath.length() > 0 ) {
289  if ( 0 == parentObj ) {
290  if ( objPath[0] != SEPARATOR ) {
291  return registerAddress(m_root, objPath, pAddress);
292  }
293  std::string::size_type sep = objPath.find(SEPARATOR,1);
294  if ( sep != std::string::npos ) {
295  std::string p_path (objPath, 0, sep);
296  if ( p_path == m_rootName ) {
297  std::string o_path (objPath, sep, objPath.length());
298  return registerAddress(m_root, o_path, pAddress);
299  }
300  }
301  return INVALID_PARENT;
302  }
303  if ( objPath[0] != SEPARATOR ) {
305  path = SEPARATOR;
306  path += objPath;
307  return registerAddress(parentObj, path, pAddress);
308  }
309  RegEntry* par_entry = CAST_REGENTRY(RegEntry*,parentObj);
310  if ( 0 != par_entry ) {
311  std::string::size_type sep = objPath.rfind(SEPARATOR);
312  if ( sep > 0 && sep != std::string::npos ) {
313  std::string p_path (objPath, 0, sep);
314  std::string o_path (objPath, sep, objPath.length());
315  RegEntry* p_entry = par_entry->findLeaf(p_path);
316  // Create default object leafs if the
317  // intermediate nodes are not present
318  if ( 0 == p_entry && m_forceLeaves ) {
319  DataObject *pLeaf = createDefaultObject();
320  StatusCode sc = registerObject(par_entry->identifier(),
321  p_path,
322  pLeaf);
323  if ( ! sc.isSuccess() ) {
324  delete pLeaf;
325  }
326  p_entry = par_entry->findLeaf(p_path);
327  }
328  if ( 0 != p_entry ) {
329  return registerAddress(p_entry, o_path, pAddress);
330  }
331  return INVALID_PARENT;
332  }
333  StatusCode status = par_entry->add(objPath, pAddress);
334  if ( status.isSuccess() ) {
335  return status;
336  }
337  return DOUBL_OBJ_PATH;
338  }
339  return INVALID_PARENT;
340  }
341  return INVALID_OBJ_PATH;
342  }
343  return INVALID_ROOT;
344 }
345 
348  if ( fullPath.length() > 0 ) {
349  IRegistry* pRegistry = 0;
350  if ( fullPath[0] != SEPARATOR ) {
351  return unregisterAddress(m_root, fullPath);
352  }
353  return unregisterAddress(pRegistry, fullPath);
354  }
355  return INVALID_OBJ_PATH;
356 }
357 
360  const std::string& objPath) {
361  IRegistry* pRegistry = (0 == pParent) ? 0 : pParent->registry();
362  return unregisterAddress(pRegistry, objPath);
363 }
364 
367  const std::string& objPath) {
368  if ( checkRoot() ) {
369  if ( objPath.length() > 0 ) {
370  if ( 0 == pParent ) {
371  if ( objPath[0] != SEPARATOR ) {
372  return unregisterAddress(m_root, objPath);
373  }
374  std::string::size_type sep = objPath.find(SEPARATOR,1);
375  if ( sep != std::string::npos ) {
376  std::string p_path (objPath, 0, sep);
377  if ( p_path == m_rootName ) {
378  std::string o_path (objPath, sep, objPath.length());
379  return unregisterAddress(m_root, o_path);
380  }
381  }
382  return INVALID_PARENT;
383  }
384  if ( objPath[0] != SEPARATOR ) {
386  path = SEPARATOR;
387  path += objPath;
388  return unregisterAddress(pParent, path);
389  }
390  RegEntry* node_entry = CAST_REGENTRY(RegEntry*,pParent);
391  if ( 0 != node_entry ) {
392  RegEntry* leaf_entry = node_entry->findLeaf(objPath);
393  if ( 0 != leaf_entry ) {
394  std::string::size_type sep = objPath.rfind(SEPARATOR);
395  if ( sep > 0 && sep != std::string::npos ) {
396  std::string path = objPath.substr(sep);
397  return unregisterAddress(leaf_entry->parent(), path);
398  }
399  StatusCode status = node_entry->remove(objPath);
400  if ( status.isSuccess() ) {
401  return status;
402  }
403  }
404  }
405  return INVALID_PARENT;
406  }
407  return INVALID_OBJ_PATH;
408  }
409  return INVALID_ROOT;
410 }
411 
414  DataObject* pObject) {
415  return registerObject(0, fullPath, pObject);
416 }
417 
418 
421  const std::string& objPath,
422  DataObject* pObject) {
423  DataObject* pO = 0;
424  StatusCode status = retrieveObject(parentPath, pO);
425  if ( !status.isSuccess() && m_forceLeaves ) {
426  pO = createDefaultObject();
427  status = registerObject(parentPath, pO);
428  if ( !status.isSuccess() ) {
429  pO->release();
430  }
431  }
432  if ( status.isSuccess() ) {
433  status = registerObject(pO, objPath, pObject);
434  }
435  return status;
436 }
437 
440  int item,
441  DataObject* pObject) {
442  return registerObject(parentPath, itemToPath(item), pObject);
443 }
444 
447  int item,
448  DataObject* pObject) {
449  return registerObject(parentObj, itemToPath(item), pObject);
450 }
451 
454  const std::string& objPath,
455  DataObject* pObject) {
456  if ( checkRoot() ) {
457  if ( 0 == parentObj ) {
458  if ( objPath.length() > 0 ) {
459  if ( objPath[0] == SEPARATOR ) {
460  std::string::size_type sep = objPath.find(SEPARATOR,1);
461  if ( sep != std::string::npos ) {
462  std::string p_path (objPath, 0, sep);
463  std::string o_path (objPath, sep, objPath.length());
464  return registerObject(p_path, o_path, pObject);
465  }
466  }
467  else {
468  return registerObject(m_rootName, objPath, pObject);
469  }
470  }
471  return INVALID_OBJ_PATH;
472  }
473  RegEntry* node_entry = CAST_REGENTRY(RegEntry*,parentObj->registry());
474  if ( 0 != node_entry ) {
475  StatusCode status = INVALID_PARENT;
476  std::string::size_type sep = objPath.find(SEPARATOR,1);
477  if ( sep != std::string::npos ) {
478  std::string p_path (objPath, 0, sep);
479  std::string o_path (objPath, sep, objPath.length());
480  RegEntry* par_entry = node_entry->findLeaf(p_path);
481  // Create default object leafs if the
482  // intermediate nodes are not present
483  if ( 0 == par_entry && m_forceLeaves ) {
484  DataObject *pLeaf = createDefaultObject();
485  StatusCode sc = registerObject(parentObj, p_path, pLeaf);
486  if ( ! sc.isSuccess() ) {
487  delete pLeaf;
488  }
489  par_entry = node_entry->findLeaf(p_path);
490  }
491  else if ( 0 != par_entry && par_entry->object() == 0 ) {
492  status = retrieveEntry( node_entry, p_path, par_entry);
493  if ( !status.isSuccess() && !par_entry->address() && m_forceLeaves ) {
494  DataObject *pLeaf = createDefaultObject();
495  StatusCode sc = registerObject(parentObj, p_path, pLeaf);
496  if ( ! sc.isSuccess() ) {
497  delete pLeaf;
498  }
499  par_entry = node_entry->findLeaf(p_path);
500  }
501  }
502  node_entry = par_entry;
503  if ( 0 != node_entry ) {
504  DataObject* obj = node_entry->object();
505  if ( 0 != obj ) {
506  status = registerObject( obj, o_path, pObject );
507  }
508  }
509  }
510  else {
511  RegEntry* leaf = node_entry->findLeaf(objPath);
512  if ( 0 == leaf ) {
513  status = node_entry->add( objPath, pObject );
514  }
515  else {
516  DataObject* obj = leaf->object();
517  if ( 0 == obj ) {
518  if (0 == pObject) {
519  error() << "registerObject: trying to register null DataObject" << endmsg;
520  return StatusCode::FAILURE;
521  }
522  else {
523  pObject->setRegistry(leaf);
524  }
525  leaf->setAddress(0);
526  leaf->setObject(pObject);
527  status = StatusCode::SUCCESS;
528  }
529  else {
530  status = DOUBL_OBJ_PATH;
531  }
532  }
533  }
534  return status;
535  }
536  return INVALID_PARENT;
537  }
538  return INVALID_ROOT;
539 }
540 
543  DataObject* pObject = 0;
544  StatusCode status = findObject(fullPath, pObject);
545  if ( status.isSuccess() ) {
546  RegEntry* pEntry = CAST_REGENTRY(RegEntry*,pObject->registry());
547  if ( 0 != pEntry ) {
548  if ( pEntry->isEmpty() ) {
549  RegEntry* pParent = pEntry->parentEntry();
550  if ( 0 != pParent ) {
551  if ( 0 != pObject ) {
552  pObject->addRef();
553  }
554  pParent->remove(pEntry);
555  return StatusCode::SUCCESS;
556  }
557  return INVALID_PARENT;
558  }
559  return DIR_NOT_EMPTY;
560  }
561  return INVALID_ROOT;
562  }
563  return status;
564 }
565 
568  const std::string& objPath) {
569  DataObject* pO = 0;
570  StatusCode status = findObject(parentPath, pO);
571  if ( status.isSuccess() ) {
572  status = unregisterObject(pO, objPath);
573  }
574  return status;
575 }
576 
579  return unregisterObject(parentPath, itemToPath(item));
580 }
581 
584  if ( checkRoot() ) {
585  RegEntry* entry = m_root->findLeaf(pObject);
586  if ( 0 != entry ) {
587  RegEntry* parent = entry->parentEntry();
588  if ( 0 != parent ) {
589  if ( entry->isEmpty() ) {
590  if ( 0 != entry->object() ) {
591  entry->object()->addRef();
592  }
593  if ( 0 != parent ) {
594  parent->remove(entry);
595  }
596  return SUCCESS;
597  }
598  return INVALID_PARENT;
599  }
600  return DIR_NOT_EMPTY;
601  }
602  return INVALID_OBJECT;
603  }
604  return INVALID_ROOT;
605 }
606 
609  const std::string& objectPath) {
610  if ( checkRoot() ) {
611  try {
612  RegEntry* parent = CAST_REGENTRY(RegEntry*,pParentObj->registry());
613  if ( 0 != parent ) {
614  RegEntry* entry = parent->findLeaf(objectPath);
615  if ( 0 != entry ) {
616  if ( entry->isEmpty() ) {
617  if ( 0 != entry->object() ) {
618  entry->object()->addRef();
619  }
620  parent->remove(entry);
621  return SUCCESS;
622  }
623  return DIR_NOT_EMPTY;
624  }
625  return INVALID_OBJECT;
626  }
627  }
628  catch(...) {
629  }
630  return INVALID_PARENT;
631  }
632  return INVALID_ROOT;
633 }
634 
637  return unregisterObject(pParentObj, itemToPath(item));
638 }
639 
643 {
644  if ( m_enableFaultHdlr ) {
645  IRegistry* pLeaf = 0;
646  if ( pReg && path.length() == 0 ) {
647  DataIncident incident(name(), m_faultName, pReg->identifier());
648  m_incidentSvc->fireIncident(incident);
649  return pReg->object();
650  }
651  else if ( pReg ) {
652  std::string p = pReg->identifier();
653  if (path[0] != SEPARATOR ) p += SEPARATOR;
654  p += path;
655  DataIncident incident(name(), m_faultName, p);
656  m_incidentSvc->fireIncident(incident);
657  pLeaf = m_root->findLeaf(p);
658  }
659  else {
661  if (path[0] != SEPARATOR ) p += SEPARATOR;
662  p += path;
663  DataIncident incident(name(), m_faultName, p);
664  m_incidentSvc->fireIncident(incident);
665  pLeaf = m_root->findLeaf(p);
666  }
667  if ( pLeaf ) {
668  return pLeaf->object();
669  }
670  }
671  return 0;
672 }
673 
678  IConversionSvc* pLoader = getDataLoader(pRegistry);
679  return loadObject(pLoader, pRegistry);
680 }
681 
686  StatusCode status = INVALID_OBJ_ADDR;
687  DataObject* pObject = 0;
688  if ( 0 == pLoader ) { // Precondition: Data loader must be present
689  if (handleDataFault(pRegistry) != 0) return SUCCESS;
690  else return NO_DATA_LOADER;
691  }
692  if ( 0 == pRegistry ) { // Precondition: Directory must be valid
693  if (handleDataFault(pRegistry) != 0) return SUCCESS;
694  else return INVALID_OBJ_ADDR;
695  }
696 
697  VERMSG << "Requested object " << pRegistry->identifier() << endmsg;
698 
699  if ( m_enableAccessHdlr ) {
700  // Fire data access incident
701  DataIncident incident(name(), m_accessName, pRegistry->identifier());
702  m_incidentSvc->fireIncident(incident);
703  }
704  if ( m_inhibitPathes.size() > 0 ) {
705  const std::string& ident = pRegistry->identifier();
708  if ( inhibit != m_inhibitPathes.end() ) {
709  return NO_ACCESS;
710  }
711  }
712  IOpaqueAddress* pAddress = pRegistry->address();
713  if ( 0 == pAddress ) { // Precondition:
714  return INVALID_OBJ_ADDR; // Address must be valid
715  }
716  try {
717  status = pLoader->createObj(pAddress, pObject); // Call data loader
718  if ( status.isSuccess() ) {
719 
720  VERMSG << "Object " << pRegistry->identifier() << " created" << endmsg;
721 
722  RegEntry *pEntry = CAST_REGENTRY(RegEntry*,pRegistry);
723  pEntry->setObject(pObject);
724 
725  VERMSG << "Filling object " << pRegistry->identifier() << endmsg;
726  status = pLoader->fillObjRefs(pAddress, pObject);
727  }
728  }
729  catch( const GaudiException& exc ) {
730  if ( handleDataFault(pRegistry) != 0 ) {
731  return SUCCESS;
732  }
733  throw GaudiException("GaudiException in loadObject() " + pRegistry->identifier(),
734  name(), StatusCode::FAILURE, exc);
735  }
736  catch( const std::exception& x) {
737  if ( handleDataFault(pRegistry) != 0 ) {
738  return SUCCESS;
739  }
740  throw GaudiException("std::exception in loadObject() " + pRegistry->identifier() +
741  ": " + System::typeinfoName(typeid(x)) + ", " + x.what(),
743  }
744  catch(...) {
745  if ( handleDataFault(pRegistry) != 0 ) {
746  return SUCCESS;
747  }
748  throw GaudiException("UNKN exception in loadObject() " + pRegistry->identifier(),
750  }
751  if ( !status.isSuccess() ) {
752  if ( handleDataFault(pRegistry) != 0 ) {
753  return StatusCode::SUCCESS;
754  }
755  }
756  ON_VERBOSE if ( status.isSuccess() ) {
757  verbose() << "Object " << pRegistry->identifier() << " successfully loaded" << endmsg;
758  }
759  return status;
760 }
761 
764  const std::string& path,
765  RegEntry*& pEntry) {
766  std::string::size_type sep = path.find(SEPARATOR,1);
767  StatusCode status = StatusCode(INVALID_ROOT,true);
768  pEntry = 0;
769  // A.Valassi 16.08.2001 avoid core dump if store is empty
770  if ( checkRoot() ) {
771  if ( 0 == parentObj ) {
772  if ( path.length() == 0 || path == m_rootName ) {
773  return retrieveEntry(m_root, "", pEntry);
774  }
775  else if ( path[0] != SEPARATOR ) {
776  return retrieveEntry(m_root, path, pEntry);
777  }
778  else if ( sep != std::string::npos ) {
779  if ( m_root->object() == 0 ) {
780  RegEntry* r = 0;
781  status = retrieveEntry(m_root, "", r);
782  if ( !status.isSuccess() ) {
783  return status;
784  }
785  }
786  std::string o_path (path, sep, path.length());
787  return retrieveEntry(m_root, o_path, pEntry);
788  }
789  return INVALID_OBJ_PATH;
790  }
791  if ( sep != std::string::npos ) { // the string contains a separator (after pos 0)
792  std::string p_path (path,0,sep);
793  std::string o_path (path,sep,path.length());
794  if (!parentObj->object()) { // if the parent object has not been loaded yet, load it now
795  status = loadObject(parentObj);
796  if ( !status.isSuccess() ) {
797  return status;
798  }
799  }
800  RegEntry* root_entry = parentObj->findLeaf(p_path);
801  if ( !root_entry && m_enableFaultHdlr ) {
802  // If not even the parent is there, an incident
803  // to load the parent must be fired...
804  handleDataFault(parentObj, p_path);
805  root_entry = parentObj->findLeaf(p_path);
806  }
807  if ( root_entry ) {
808  DataObject* pO = root_entry->object();
809  if ( 0 == pO ) {
810  // Object is not loaded: load the object if at all possible
811  status = loadObject(root_entry);
812  if ( !status.isSuccess() ) {
813  return status;
814  }
815  }
816  if ( root_entry->isSoft() ) {
817  root_entry = CAST_REGENTRY(RegEntry*,pO->registry());
818  }
819  return retrieveEntry (root_entry, o_path, pEntry);
820  }
821  return status;
822  }
823  else if ( path.length() == 0 ) {
824  pEntry = parentObj;
825  }
826  else {
827  if (!parentObj->object()) { // if the parent object has not been loaded yet, load it now
828  status = loadObject(parentObj);
829  if ( !status.isSuccess() ) {
830  return status;
831  }
832  }
833  // last leave in search: find leaf and load
834  pEntry = parentObj->findLeaf(path);
835  // If no registry entry was found, trigger incident for action-on-demand
836  if ( !pEntry && m_enableFaultHdlr ) {
837  handleDataFault(parentObj, path);
838  pEntry = (0==path.length()) ? parentObj : parentObj->findLeaf(path);
839  }
840  }
841  // Check results and return
842  if ( 0 == pEntry ) {
843  status = INVALID_OBJ_PATH;
844  }
845  else if ( 0 == pEntry->object() ) {
846  status = loadObject(pEntry);
847  }
848  else if ( m_enableAccessHdlr ) {
849  // Fire data access incident
850  // I do not know if this is a good idea....
851  // This fires too often!
852  //
853  //DataIncident incident(name(), m_accessName, pEntry->identifier());
854  //m_incidentSvc->fireIncident(incident);
855  status = SUCCESS;
856  }
857  else {
858  status = SUCCESS;
859  }
860  }
861  return status;
862 }
863 
866  const std::string& path,
867  DataObject*& pObject) {
868  pObject = 0;
869  RegEntry *result = 0, *parent = CAST_REGENTRY(RegEntry*,pRegistry);
870  StatusCode status = retrieveEntry(parent, path, result);
871  if ( status.isSuccess() ) {
872  pObject = result->object();
873  }
874  return status;
875 }
876 
879  DataObject*& pObject) {
880  IRegistry* nullDir = 0;
881  return retrieveObject(nullDir, fullPath, pObject);
882 }
883 
886  const std::string& objectPath,
887  DataObject*& pObject) {
888  DataObject* parent = 0;
889  StatusCode status = retrieveObject(parentPath, parent);
890  if ( status.isSuccess() ) {
891  status = retrieveObject (parent, objectPath, pObject);
892  }
893  return status;
894 }
895 
898  int item,
899  DataObject*& pObject) {
900  return retrieveObject(parentPath, itemToPath(item), pObject);
901 }
902 
905  const std::string& path,
906  DataObject*& pObject) {
907  IRegistry* pRegistry = (0==parentObj) ? 0 : parentObj->registry();
908  return retrieveObject(pRegistry, path, pObject);
909 }
910 
913  int item,
914  DataObject*& pObject) {
915  return retrieveObject(parentObj, itemToPath(item), pObject);
916 }
917 
920  const std::string& path,
921  DataObject*& pObject) {
922  pObject = 0;
923  IRegistry* pReg = (0==pRegistry) ? m_root : pRegistry;
924  RegEntry* root_entry = CAST_REGENTRY(RegEntry*, pReg);
925  if ( 0 != root_entry ) {
926  if ( path.length() > 0 ) {
927  pReg = root_entry->find(path);
928  }
929  if ( 0 == pReg ) {
930  return INVALID_OBJ_PATH;
931  }
932  pObject = pReg->object();
933  }
934  return (0 == pObject) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
935 }
936 
939  DataObject*& pObject) {
940  pObject = 0;
941  if ( checkRoot() ) {
942  if ( path.length() == 0 || path == m_rootName ) {
943  pObject = m_root->object();
944  return (0 == pObject) ? OBJ_NOT_LOADED : IDataProviderSvc_NO_ERROR;
945  }
946  else if ( path[0] != SEPARATOR ) {
947  return findObject(m_rootName, path, pObject);
948  }
949  return findObject((IRegistry*)0, path, pObject);
950  }
951  return INVALID_ROOT;
952 }
953 
956  const std::string& objectPath,
957  DataObject*& pObject) {
958  DataObject* parent = 0;
959  StatusCode status = findObject(parentPath, parent);
960  if ( status.isSuccess() ) {
961  status = findObject (parent, objectPath, pObject);
962  }
963  return status;
964 }
965 
968  int item, DataObject*& pObject) {
969  return findObject(parentPath, itemToPath(item), pObject);
970 }
971 
974  int item,
975  DataObject*& pObject) {
976  return findObject(parentObj, itemToPath(item), pObject);
977 }
978 
981  const std::string& path,
982  DataObject*& pObject) {
983  IRegistry* pDir = (0==parentObj) ? 0 : parentObj->registry();
984  return findObject(pDir, path, pObject);
985 }
986 
989  DataObject* pO = 0;
990  StatusCode status = findObject(updatePath, pO);
991  if ( status.isSuccess() ) {
992  return updateObject(pO);
993  }
994  return retrieveObject(updatePath, pO);
995 }
996 
999  if ( 0 == pRegistry ) { // Precondition:
1000  return INVALID_OBJ_ADDR; // Addres must be valid
1001  }
1002  DataObject* toUpdate = pRegistry->object();
1003  if ( 0 == toUpdate ) { // Try first to load
1004  return loadObject(pRegistry);
1005  }
1006  return updateObject(toUpdate);
1007 }
1008 
1011  StatusCode status = INVALID_OBJ_ADDR;
1012  if ( 0 == toUpdate ) { // Precondition:
1013  return INVALID_OBJECT; // Address must be valid
1014  }
1015  IRegistry* pRegistry = toUpdate->registry(); // Precondition:
1016  if ( 0 == pRegistry ) { // Need valid registry
1017  return INVALID_OBJECT;
1018  }
1019  IOpaqueAddress* pAddress = pRegistry->address(); // Precondition:
1020  if ( 0 == pAddress ) { // Need valid address
1021  return INVALID_OBJ_ADDR;
1022  }
1023  IConversionSvc* pLoader = getDataLoader(pRegistry);
1024  if ( 0 == pLoader ) { // Precondition:
1025  return NO_DATA_LOADER; // Data loader must be present
1026  }
1027  if ( m_inhibitPathes.size() > 0 ) {
1028  const std::string& ident = pRegistry->identifier();
1031  if ( inhibit != m_inhibitPathes.end() ) {
1032  return NO_ACCESS;
1033  }
1034  }
1035  try {
1036  status = pLoader->updateObj(pAddress, toUpdate); // Call data loader
1037  if ( status.isSuccess() ) {
1038  status = pLoader->updateObjRefs(pAddress, toUpdate);
1039  }
1040  }
1041  catch( const GaudiException& exc ) {
1042  throw GaudiException("GaudiException in updateObject() " +
1043  pRegistry->name(),
1044  name(),
1045  StatusCode::FAILURE, exc);
1046  }
1047  catch( const std::exception& x) {
1048  throw GaudiException("std::exception in updateObject() " +
1049  pRegistry->name() + ": " +
1050  System::typeinfoName(typeid(x)) + ", " +
1051  x.what(),
1053  }
1054  catch(...) {
1055  throw GaudiException("UNKN exception in updateObject() " +
1056  pRegistry->name(),
1058  }
1059  return status;
1060 }
1061 
1064  const std::string& updatePath) {
1065  DataObject* pParent = 0;
1066  StatusCode status = findObject(parentPath, pParent);
1067  if ( status.isSuccess() ) {
1068  status = updateObject( pParent, updatePath);
1069  }
1070  return status;
1071 }
1072 
1075  const std::string& updatePath) {
1076  DataObject* pObject = 0;
1077  StatusCode status = findObject(parent, updatePath, pObject);
1078  if ( status.isSuccess() ) {
1079  status = updateObject(pObject);
1080  }
1081  return status;
1082 }
1083 
1084 // Link object
1086  const std::string& objPath, DataObject* to) {
1087  if ( checkRoot() ) {
1088  try {
1089  RegEntry* from_entry = CAST_REGENTRY(RegEntry*,from);
1090  if ( 0 != from_entry ) {
1091  // First check if both objects are already registered to the store
1092  RegEntry* to_entry = m_root->findLeaf(to);
1093  if ( 0 == to_entry ) {
1094  return INVALID_OBJECT;
1095  }
1096  else {
1097  std::string::size_type sep = objPath.rfind(SEPARATOR);
1098  if ( sep > 0 && sep != std::string::npos ) { // in case the objPath is a sub-directory itself
1099  DataObject* pO = 0;
1100  std::string fromPath(objPath, 0, sep);
1101  StatusCode sc = retrieveObject(from, fromPath, pO);
1102  if ( sc.isSuccess() ) {
1103  std::string toPath(objPath, sep, objPath.length());
1104  sc = linkObject(pO->registry(), toPath, to);
1105  }
1106  return sc;
1107  }
1108  // Now register the soft link
1109  StatusCode status = from_entry->add( objPath, to, true);
1110  return status.isSuccess() ?
1111  IDataProviderSvc_NO_ERROR : DOUBL_OBJ_PATH;
1112  }
1113  }
1114  }
1115  catch (...) {
1116  }
1117  return INVALID_PARENT;
1118  }
1119  return INVALID_ROOT;
1120 }
1121 
1124  DataObject* to) {
1125  if ( fullPath.length() > 0 ) {
1126  if ( fullPath[0] != SEPARATOR ) {
1127  return linkObject(m_rootName, fullPath, to);
1128  }
1129  std::string::size_type sep = fullPath.rfind(SEPARATOR);
1130  std::string objPath(fullPath, sep, fullPath.length());
1131  std::string fromPath(fullPath, 0, sep);
1132  return linkObject( fromPath, objPath, to);
1133  }
1134  return INVALID_OBJ_PATH;
1135 }
1136 
1139  const std::string& objPath,
1140  DataObject* to) {
1141  DataObject* pO = 0;
1142  StatusCode status = retrieveObject(from, pO);
1143  if ( status.isSuccess() ) {
1144  return linkObject(pO->registry(), objPath, to);
1145  }
1146  return status;
1147 }
1148 
1151  const std::string& objPath,
1152  DataObject* to) {
1153  if ( 0 != from ) {
1154  IRegistry* from_entry = from->registry();
1155  if ( 0 != from_entry ) {
1156  return linkObject( from_entry, objPath, to);
1157  }
1158  }
1159  return INVALID_PARENT;
1160 }
1161 
1164  const std::string& objPath) {
1165  if ( checkRoot() ) {
1166  try {
1167  RegEntry* from_entry = CAST_REGENTRY(RegEntry*,from);
1168  if ( 0 != from_entry ) {
1169  std::string::size_type sep = objPath.rfind(SEPARATOR);
1170  if ( sep > 0 && sep != std::string::npos ) { // in case the objPath is a sub-directory itself
1171  DataObject* pO = 0;
1172  std::string fromPath(objPath, 0, sep);
1173  StatusCode sc = findObject(from, fromPath, pO);
1174  if ( sc.isSuccess() ) {
1175  std::string toPath(objPath, sep, objPath.length());
1176  sc = unlinkObject(pO->registry(), toPath);
1177  }
1178  return sc;
1179  }
1180  StatusCode status = from_entry->remove( objPath );
1181  if ( status.isSuccess() ) {
1182  return status;
1183  }
1184  return INVALID_OBJ_PATH;
1185  }
1186  }
1187  catch (...) {
1188  }
1189  return INVALID_PARENT;
1190  }
1191  return INVALID_ROOT;
1192 }
1193 
1196  if ( fullPath.length() > 0 ) {
1197  if ( fullPath[0] != SEPARATOR ) {
1198  return unlinkObject(m_rootName, fullPath);
1199  }
1200  std::string::size_type sep = fullPath.rfind(SEPARATOR);
1201  std::string objPath(fullPath, sep, fullPath.length());
1202  std::string fromPath(fullPath, 0, sep);
1203  return unlinkObject(fromPath, objPath);
1204  }
1205  return INVALID_OBJ_PATH;
1206 }
1207 
1210  const std::string& objPath) {
1211  DataObject* pObject = 0;
1212  StatusCode status = findObject(from, pObject);
1213  if ( status.isSuccess() ) {
1214  status = unlinkObject(pObject->registry(), objPath);
1215  }
1216  return status;
1217 }
1218 
1221  const std::string& objPath) {
1222  if ( checkRoot() ) {
1223  IRegistry* from_entry = m_root->findLeaf(from);
1224  return unlinkObject(from_entry, objPath);
1225  }
1226  return INVALID_ROOT;
1227 }
1228 
1232  if ( i == m_preLoads.end() ) {
1233  m_preLoads.push_back(item);
1234  }
1235  return StatusCode::SUCCESS;
1236 }
1237 
1240  return addPreLoadItem( DataStoreItem(itemPath,1) );
1241 }
1242 
1247  if ( i != m_preLoads.end() ) {
1249  }
1250  return StatusCode::SUCCESS;
1251 }
1252 
1255  return removePreLoadItem( DataStoreItem(itemPath,1) );
1256 }
1257 
1261  return StatusCode::SUCCESS;
1262 }
1263 
1265 StatusCode DataSvc::preLoad(int depth, int load_depth, DataObject* pObject) {
1266  //unused: StatusCode sc = StatusCode::FAILURE;
1267  if ( 0 != pObject && depth++ < load_depth ) {
1268  RegEntry* dir = CAST_REGENTRY(RegEntry*,pObject->registry());
1269  if ( 0 != dir ) {
1270  for (RegEntry::Iterator i = dir->begin(); i != dir->end(); i++ ) {
1271  DataObject *pObj = 0;
1272  StatusCode status = retrieveObject(pObject, (*i)->name(), pObj);
1273  if ( status.isSuccess() && depth < load_depth ) {
1274  preLoad(depth, load_depth, pObj).ignore();
1275  }
1276  }
1277  }
1278  }
1279  return StatusCode::SUCCESS;
1280 }
1281 
1284  DataObject* pObj = 0;
1285  for (LoadItems::iterator i = m_preLoads.begin(); i != m_preLoads.end(); i++) {
1286  StatusCode sc = retrieveObject( (*i).path(), pObj);
1287  int load_depth = (*i).depth();
1288  if ( sc.isSuccess() && load_depth > 1 ) {
1289  preLoad(1, load_depth, pObj).ignore();
1290  }
1291  }
1292  return StatusCode::SUCCESS;
1293 }
1294 
1297  // Nothing to do: just call base class initialisation
1299  if ( !sc.isSuccess() ) {
1300  return sc;
1301  }
1302  sc = service("IncidentSvc", m_incidentSvc, true);
1303  if ( UNLIKELY(!sc.isSuccess()) ) {
1304  error() << "Failed to access incident service." << endmsg;
1305  }
1306  return sc;
1307 }
1308 
1311  StatusCode sc;
1312  // the finalize part is copied here
1313  setDataLoader(0).ignore();
1314  resetPreLoad().ignore();
1315  clearStore().ignore();
1316  if ( m_incidentSvc ) {
1318  m_incidentSvc = 0;
1319  }
1320  // re-initialize the base class
1321  sc = Service::reinitialize();
1322  if ( UNLIKELY(!sc.isSuccess()) ) {
1323  error() << "Unable to reinitialize base class" << endmsg;
1324  return sc;
1325  }
1326  // the initialize part is copied here
1327  sc = service("IncidentSvc", m_incidentSvc, true);
1328  if ( UNLIKELY(!sc.isSuccess()) ) {
1329  error() << "Failed to access incident service." << endmsg;
1330  return sc;
1331  }
1332  // return
1333  return StatusCode::SUCCESS;
1334 }
1335 
1338  // Nothing to do: just call base class initialisation
1339  setDataLoader(0).ignore();
1340  resetPreLoad().ignore();
1341  clearStore().ignore();
1342  if ( m_incidentSvc ) {
1344  m_incidentSvc = 0;
1345  }
1346  return Service::finalize();
1347 }
1348 
1351  return( (CLID)m_rootCLID );
1352 }
1353 
1356  return( m_rootName );
1357 }
1358 
1361  return new DataObject();
1362 }
1363 
1368  return m_dataLoader;
1369 }
1370 
1373 : base_class(name,svc), m_rootCLID( /*CLID_Event*/ 110),
1374  m_rootName( "/Event"), m_root(0)
1375 {
1376  m_dataLoader = 0;
1377  m_inhibitMap = 0;
1378  m_incidentSvc = 0;
1379  m_forceLeaves = false;
1380  m_enableFaultHdlr = false;
1381  m_enableAccessHdlr = false;
1382  m_faultName = "DataFault";
1383  m_accessName = "DataAccess";
1384  declareProperty("RootCLID", m_rootCLID);
1385  declareProperty("RootName", m_rootName);
1386  declareProperty("ForceLeaves", m_forceLeaves);
1387  declareProperty("InhibitPathes", m_inhibitPathes);
1388  declareProperty("DataFaultName", m_faultName);
1389  declareProperty("DataAccessName", m_accessName);
1390  declareProperty("EnableFaultHandler", m_enableFaultHdlr);
1391  declareProperty("EnableAccessHandler", m_enableAccessHdlr);
1392 }
1393 
1396  setDataLoader(0).ignore();
1397  resetPreLoad().ignore();
1398  clearStore().ignore();
1399 }

Generated at Wed Jan 30 2013 17:13:40 for Gaudi Framework, version v23r6 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004