Changes for #82873: Module debugging broken (Christian)
[u/mrichter/AliRoot.git] / STEER / AliCDBManager.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 //-------------------------------------------------------------------------
16 //   Implementation of AliCDBManager and AliCDBParam classe
17 //   Author: Alberto Colla 
18 //   e-mail: Alberto.Colla@cern.ch
19 //-------------------------------------------------------------------------
20
21 #include "AliCDBManager.h"
22 #include "AliCDBStorage.h"
23 #include "AliLog.h"
24 #include "AliCDBDump.h"
25 #include "AliCDBLocal.h"
26 #include "AliCDBGrid.h"
27 #include "AliCDBEntry.h"
28 #include "AliCDBHandler.h"
29
30 #include <TObjString.h>
31 #include <TSAXParser.h>
32 #include <TFile.h>
33 #include <TUUID.h>
34 #include <TGrid.h>
35
36 ClassImp(AliCDBParam)
37
38 ClassImp(AliCDBManager)
39
40 //TODO OCDB and Reference folder should not be fully hardcoded but built from run number (or year/LHC period)
41 TString AliCDBManager::fgkCondUri("alien://folder=/alice/cern.ch/user/a/aliprod/testCDB/CDB?user=aliprod");
42 TString AliCDBManager::fgkRefUri("alien://folder=/alice/cern.ch/user/a/aliprod/testCDB/Reference?user=aliprod");
43 TString AliCDBManager::fgkMCIdealStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Ideal");
44 TString AliCDBManager::fgkMCFullStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Full");
45 TString AliCDBManager::fgkMCResidualStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Residual");
46 TString AliCDBManager::fgkOCDBFolderXMLfile("alien:///alice/data/OCDBFoldervsRunRange.xml");
47 AliCDBManager* AliCDBManager::fgInstance = 0x0;
48
49 //_____________________________________________________________________________
50 AliCDBManager* AliCDBManager::Instance(TMap *entryCache, Int_t run)
51 {
52 // returns AliCDBManager instance (singleton)
53
54         if (!fgInstance) {
55                 fgInstance = new AliCDBManager();
56                 if (!entryCache)
57                   fgInstance->Init();
58                 else
59                   fgInstance->InitFromCache(entryCache,run);
60         }
61
62         return fgInstance;
63 }
64
65 //_____________________________________________________________________________
66 void AliCDBManager::Init() {
67 // factory registering
68
69         RegisterFactory(new AliCDBDumpFactory());
70         RegisterFactory(new AliCDBLocalFactory()); 
71         // AliCDBGridFactory is registered only if AliEn libraries are enabled in Root
72         if(!gSystem->Exec("root-config --has-alien |grep yes 2>&1 > /dev/null")){ // returns 0 if yes
73                 AliInfo("AliEn classes enabled in Root. AliCDBGrid factory registered.");
74                 RegisterFactory(new AliCDBGridFactory());
75                 fCondParam = CreateParameter(fgkCondUri);
76                 fRefParam = CreateParameter(fgkRefUri);
77         }
78
79         InitShortLived();
80 }
81
82 //_____________________________________________________________________________
83 void AliCDBManager::InitFromCache(TMap *entryCache, Int_t run) {
84 // initialize manager from existing cache
85 // used on the slaves in case of parallel reconstruction
86   SetRun(run);
87
88   TIter iter(entryCache->GetTable());
89   TPair* pair = 0;
90
91   while((pair = dynamic_cast<TPair*> (iter.Next()))){
92     fEntryCache.Add(pair->Key(),pair->Value());
93   }
94   // fEntry is the new owner of the cache
95   fEntryCache.SetOwnerKeyValue(kTRUE,kTRUE);
96   entryCache->SetOwnerKeyValue(kFALSE,kFALSE);
97   AliInfo(Form("%d cache entries have been loaded",fEntryCache.GetEntries()));
98 }
99
100 //_____________________________________________________________________________
101 void AliCDBManager::Destroy() {
102 // delete ALCDBManager instance and active storages
103
104         if (fgInstance) {
105                 //fgInstance->Delete();
106                 delete fgInstance;
107                 fgInstance = 0x0;
108         }
109 }
110
111 //_____________________________________________________________________________
112 AliCDBManager::AliCDBManager():
113   TObject(),
114   fFactories(),
115   fActiveStorages(),
116   fSpecificStorages(),
117   fEntryCache(),
118   fIds(0),
119   fStorageMap(0),
120   fShortLived(0),
121   fDefaultStorage(NULL),
122   fDrainStorage(NULL),
123   fCondParam(0),
124   fRefParam(0),
125   fRun(-1),
126   fCache(kTRUE),
127   fLock(kFALSE),
128   fRaw(kFALSE),
129   fStartRunLHCPeriod(-1),
130   fEndRunLHCPeriod(-1),
131   fLHCPeriod(""),
132   fKey(0)
133 {
134 // default constuctor
135         fFactories.SetOwner(1);
136         fActiveStorages.SetOwner(1);
137         fSpecificStorages.SetOwner(1);
138         fEntryCache.SetName("CDBEntryCache");
139         fEntryCache.SetOwnerKeyValue(kTRUE,kTRUE);
140
141         fStorageMap = new TMap();
142         fStorageMap->SetOwner(1);
143         fIds = new TList();
144         fIds->SetOwner(1);
145 }
146
147 //_____________________________________________________________________________
148 AliCDBManager::~AliCDBManager() {
149 // destructor
150         ClearCache();
151         DestroyActiveStorages();
152         fFactories.Delete();
153         fDrainStorage = 0x0;
154         fDefaultStorage = 0x0;
155         delete fStorageMap; fStorageMap = 0;
156         delete fIds; fIds = 0;
157         delete fCondParam;
158         delete fRefParam;
159         delete fShortLived; fShortLived = 0x0;
160 }
161
162 //_____________________________________________________________________________
163 void AliCDBManager::PutActiveStorage(AliCDBParam* param, AliCDBStorage* storage){
164 // put a storage object into the list of active storages
165
166         fActiveStorages.Add(param, storage);
167         AliDebug(1, Form("Active storages: %d", fActiveStorages.GetEntries()));
168 }
169
170 //_____________________________________________________________________________
171 void AliCDBManager::RegisterFactory(AliCDBStorageFactory* factory) {
172 // add a storage factory to the list of registerd factories
173  
174         if (!fFactories.Contains(factory)) {
175                 fFactories.Add(factory);
176         }
177 }
178
179 //_____________________________________________________________________________
180 Bool_t AliCDBManager::HasStorage(const char* dbString) const {
181 // check if dbString is a URI valid for one of the registered factories
182
183         TIter iter(&fFactories);
184
185         AliCDBStorageFactory* factory=0;
186         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
187
188                 if (factory->Validate(dbString)) {
189                         return kTRUE;
190                 }
191         }
192
193         return kFALSE;
194 }
195
196 //_____________________________________________________________________________
197 AliCDBParam* AliCDBManager::CreateParameter(const char* dbString) const {
198 // create AliCDBParam object from URI string
199
200         TIter iter(&fFactories);
201
202         AliCDBStorageFactory* factory=0;
203         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
204                 AliCDBParam* param = factory->CreateParameter(dbString);
205                 if(param) return param;
206         }
207
208         return NULL;
209 }
210
211 //_____________________________________________________________________________
212 AliCDBStorage* AliCDBManager::GetStorage(const char* dbString) {
213 // get storage object from URI string
214                 
215         AliCDBParam* param = CreateParameter(dbString);
216         if (!param) {
217                 AliError(Form("Failed to activate requested storage! Check URI: %s", dbString));
218                 return NULL;
219         }
220
221         AliCDBStorage* aStorage = GetStorage(param);
222
223         delete param;
224         return aStorage;
225 }
226
227 //_____________________________________________________________________________
228 AliCDBStorage* AliCDBManager::GetStorage(const AliCDBParam* param) {
229 // get storage object from AliCDBParam object
230         
231         // if the list of active storages already contains
232         // the requested storage, return it
233         AliCDBStorage* aStorage = GetActiveStorage(param);
234         if (aStorage) {
235                 return aStorage;
236         }
237
238         // if lock is ON, cannot activate more storages!
239         if(fLock) {
240                 if (fDefaultStorage) {
241                         AliFatal("Lock is ON, and default storage is already set: "
242                                 "cannot reset it or activate more storages!");
243                 }
244         }       
245         
246         TIter iter(&fFactories);
247
248         AliCDBStorageFactory* factory=0;
249
250         // loop on the list of registered factories
251         while ((factory = (AliCDBStorageFactory*) iter.Next())) {
252
253                 // each factory tries to create its storage from the parameter
254                 aStorage = factory->Create(param);
255                 if (aStorage) {
256                         PutActiveStorage(param->CloneParam(), aStorage);
257                         aStorage->SetURI(param->GetURI());
258                         if(fRun >= 0) {
259                                 if(aStorage->GetType() == "alien"){
260                                         aStorage->QueryCDB(fRun);
261                                 } else {
262                                         AliDebug(2,
263                                                 "Skipping query for valid files, it is used only in grid...");
264                                 }
265                         }
266                         return aStorage;
267                 }
268         }
269
270         AliError(Form("Failed to activate requested storage! Check URI: %s", param->GetURI().Data()));
271
272         return NULL;
273 }
274
275 //_____________________________________________________________________________
276 AliCDBStorage* AliCDBManager::GetActiveStorage(const AliCDBParam* param) {
277 // get a storage object from the list of active storages
278
279         return dynamic_cast<AliCDBStorage*> (fActiveStorages.GetValue(param));
280 }
281
282 //_____________________________________________________________________________
283 TList* AliCDBManager::GetActiveStorages() {
284 // return list of active storages
285 // user has responsibility to delete returned object
286
287         TList* result = new TList();
288
289         TIter iter(fActiveStorages.GetTable());
290         TPair* aPair=0;
291         while ((aPair = (TPair*) iter.Next())) {
292                 result->Add(aPair->Value());
293         }
294
295         return result;
296 }
297
298 //_____________________________________________________________________________
299 void AliCDBManager::SetDrain(const char* dbString) {
300 // set drain storage from URI string
301
302         fDrainStorage = GetStorage(dbString);   
303 }
304
305 //_____________________________________________________________________________
306 void AliCDBManager::SetDrain(const AliCDBParam* param) {
307 // set drain storage from AliCDBParam
308
309         fDrainStorage = GetStorage(param);
310 }
311
312 //_____________________________________________________________________________
313 void AliCDBManager::SetDrain(AliCDBStorage* storage) {
314 // set drain storage from another active storage
315         
316         fDrainStorage = storage;
317 }
318
319 //_____________________________________________________________________________
320 Bool_t AliCDBManager::Drain(AliCDBEntry *entry) {
321 // drain retrieved object to drain storage
322
323         AliDebug(2, "Draining into drain storage...");
324         return fDrainStorage->Put(entry);
325 }
326
327 //____________________________________________________________________________
328 void AliCDBManager::SetDefaultStorage(const char* dbString) {
329 // sets default storage from URI string
330         
331         // checking whether we are in the raw case
332         TString dbStringTemp(dbString);
333         if (dbStringTemp == "raw://")
334         {
335                 fRaw = kTRUE;
336                 AliInfo("Setting the run-number will set the corresponding OCDB for raw data reconstruction.");
337                 AliInfo("Connecting to the grid...");
338                 if(!gGrid) {
339                         TGrid::Connect("alien://","");
340                         if(!gGrid) {
341                                 AliError("Connection to alien failed!");
342                                 return;
343                         }
344                 }
345                 return;
346         }
347
348         AliCDBStorage* bckStorage = fDefaultStorage;
349         
350         fDefaultStorage = GetStorage(dbString);
351         
352         if(!fDefaultStorage) return;
353         
354         if(bckStorage && (fDefaultStorage != bckStorage)){
355                 AliWarning("Existing default storage replaced: clearing cache!");
356                 ClearCache();
357         }
358         
359         if (fStorageMap->Contains("default")) {
360                 delete fStorageMap->Remove(fStorageMap->GetValue("default"));
361         }
362         fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
363 }
364 //_____________________________________________________________________________
365 void AliCDBManager::SetDefaultStorage(const AliCDBParam* param) {
366 // set default storage from AliCDBParam object
367         
368         AliCDBStorage* bckStorage = fDefaultStorage;
369
370         fDefaultStorage = GetStorage(param);
371
372         if(!fDefaultStorage) return;
373
374         if(bckStorage && (fDefaultStorage != bckStorage)){
375                 AliWarning("Existing default storage replaced: clearing cache!");
376                 ClearCache();
377         }
378
379         if (fStorageMap->Contains("default")) {
380                 delete fStorageMap->Remove(fStorageMap->GetValue("default"));
381         }
382         fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
383 }
384
385 //_____________________________________________________________________________
386 void AliCDBManager::SetDefaultStorage(AliCDBStorage* storage) {
387 // set default storage from another active storage
388         
389         // if lock is ON, cannot activate more storages!
390         if(fLock) {
391                 if (fDefaultStorage) {
392                         AliFatal("Lock is ON, and default storage is already set: "
393                                 "cannot reset it or activate more storages!");
394                 }
395         }       
396         
397         if (!storage) {
398                 UnsetDefaultStorage();
399                 return;
400         }
401         
402         AliCDBStorage* bckStorage = fDefaultStorage;
403
404         fDefaultStorage = storage;
405
406         if(bckStorage && (fDefaultStorage != bckStorage)){
407                 AliWarning("Existing default storage replaced: clearing cache!");
408                 ClearCache();
409         }
410
411         if (fStorageMap->Contains("default")) {
412                 delete fStorageMap->Remove(fStorageMap->GetValue("default"));
413         }
414         fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
415 }
416
417 //_____________________________________________________________________________
418 void AliCDBManager::SetDefaultStorage(const char* mcString, const char* simType) {
419 // sets default storage for MC data
420 // mcString MUST be "MC", 
421 // simType can be "Ideal","Residual","Full"
422         
423         TString strmcString(mcString);
424         TString strsimType(simType);
425         TString dbString; 
426         if (strmcString != "MC"){
427                 AliFatal("Method requires first string to be MC!");
428         }
429         else {
430                 if (strsimType == "Ideal"){
431                         dbString = fgkMCIdealStorage;
432                 }
433                 else if (strsimType == "Full"){
434                         dbString = fgkMCFullStorage;
435                 }
436                 else if (strsimType == "Residual"){
437                         dbString = fgkMCResidualStorage;
438                 }
439                 else {
440                         AliFatal("Error in setting the storage for MC data, second argument MUST be either \"Ideal\" or \"Full\" or \"Residual\".");
441                 }
442
443                 SetDefaultStorage(dbString.Data());
444                 if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",fLHCPeriod.Data()));
445         }
446 }
447 //_____________________________________________________________________________
448 void AliCDBManager::SetDefaultStorageFromRun(Int_t run) {
449 // set default storage from the run number - to be used only with raw data      
450
451         // if lock is ON, cannot activate more storages!
452         if(fLock) {
453                 if (fDefaultStorage) {
454                         AliFatal("Lock is ON, and default storage is already set: "
455                                 "cannot activate default storage from run number");
456                 }
457         }       
458
459         // retrieve XML file from alien
460         if(!gGrid) {
461             TGrid::Connect("alien://","");
462             if(!gGrid) {
463                 AliError("Connection to alien failed!");
464                 return;
465             }
466         }
467         TUUID uuid;
468         TString rndname = "/tmp/";
469         rndname += "OCDBFolderXML.";
470         rndname += uuid.AsString();
471         rndname += ".xml";
472         AliDebug(2, Form("file to be copied = %s", fgkOCDBFolderXMLfile.Data()));
473         if (!TFile::Cp(fgkOCDBFolderXMLfile.Data(), rndname.Data())) {
474                 AliFatal(Form("Cannot make a local copy of OCDBFolder xml file in %s",rndname.Data()));
475         }
476         AliCDBHandler* saxcdb = new AliCDBHandler();
477         saxcdb->SetRun(run);
478         TSAXParser *saxParser = new TSAXParser();
479         saxParser->ConnectToHandler("AliCDBHandler", saxcdb);  
480         saxParser->ParseFile(rndname.Data()); 
481         AliInfo(Form(" LHC folder = %s", saxcdb->GetOCDBFolder().Data()));
482         AliInfo(Form(" LHC period start run = %d", saxcdb->GetStartRunRange()));
483         AliInfo(Form(" LHC period end run = %d", saxcdb->GetEndRunRange()));
484         fLHCPeriod = saxcdb->GetOCDBFolder();
485         fStartRunLHCPeriod = saxcdb->GetStartRunRange();
486         fEndRunLHCPeriod = saxcdb->GetEndRunRange();
487
488         SetDefaultStorage(fLHCPeriod.Data());
489         if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",fLHCPeriod.Data()));
490
491 }
492
493 //_____________________________________________________________________________
494 void AliCDBManager::UnsetDefaultStorage() {
495 // Unset default storage
496         
497         // if lock is ON, action is forbidden!
498         if(fLock) {
499                 if (fDefaultStorage) {
500                         AliFatal("Lock is ON: cannot unset default storage!");
501                 }
502         }
503         
504         if (fDefaultStorage) {
505                 AliWarning("Clearing cache!");
506                 ClearCache();
507         }
508
509         fRun = fStartRunLHCPeriod = fEndRunLHCPeriod = -1;
510         fRaw = kFALSE;
511         
512         fDefaultStorage = 0x0;
513 }
514
515 //_____________________________________________________________________________
516 void AliCDBManager::SetSpecificStorage(const char* calibType, const char* dbString) {
517 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
518
519         AliCDBParam *aPar = CreateParameter(dbString);
520         if(!aPar) return;
521         SetSpecificStorage(calibType, aPar);
522         delete aPar;
523 }
524
525 //_____________________________________________________________________________
526 void AliCDBManager::SetSpecificStorage(const char* calibType, AliCDBParam* param) {
527 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
528 // Default storage should be defined prior to any specific storages, e.g.:
529 // AliCDBManager::instance()->SetDefaultStorage("alien://");
530 // AliCDBManager::instance()->SetSpecificStorage("TPC/*","local://DB_TPC");
531 // AliCDBManager::instance()->SetSpecificStorage("*/Align/*","local://DB_TPCAlign");
532 // calibType must be a valid CDB path! (3 level folder structure)
533
534
535         if(!fDefaultStorage && !fRaw) {
536                 AliError("Please activate a default storage first!");
537                 return;
538         }
539
540
541         AliCDBPath aPath(calibType);
542         if(!aPath.IsValid()){
543                 AliError(Form("Not a valid path: %s", calibType));
544                 return;
545         }
546
547         TObjString *objCalibType = new TObjString(aPath.GetPath());
548         if(fSpecificStorages.Contains(objCalibType)){
549                 AliWarning(Form("Storage \"%s\" already activated! It will be replaced by the new one",
550                                         calibType));
551                 AliCDBParam *checkPar = dynamic_cast<AliCDBParam*> (fSpecificStorages.GetValue(calibType));
552                 if(checkPar) delete checkPar;
553                 delete fSpecificStorages.Remove(objCalibType);
554         }
555         AliCDBStorage *aStorage = GetStorage(param);
556         if(!aStorage) return;
557
558         fSpecificStorages.Add(objCalibType, param->CloneParam());
559
560         if(fStorageMap->Contains(objCalibType)){
561                 delete fStorageMap->Remove(objCalibType);
562         }
563         fStorageMap->Add(objCalibType->Clone(), new TObjString(param->GetURI()));
564
565 }
566
567 //_____________________________________________________________________________
568 AliCDBStorage* AliCDBManager::GetSpecificStorage(const char* calibType) {
569 // get storage specific for detector or calibration type 
570
571         AliCDBPath calibPath(calibType);
572         if(!calibPath.IsValid()) return NULL;
573
574         AliCDBParam *checkPar = (AliCDBParam*) fSpecificStorages.GetValue(calibPath.GetPath());
575         if(!checkPar){
576                 AliError(Form("%s storage not found!", calibType));
577                 return NULL;
578         } else {
579                 return GetStorage(checkPar);
580         }
581
582 }
583
584 //_____________________________________________________________________________
585 AliCDBParam* AliCDBManager::SelectSpecificStorage(const TString& path) {
586 // select storage valid for path from the list of specific storages
587
588         AliCDBPath aPath(path);
589         if(!aPath.IsValid()) return NULL;
590
591         TIter iter(&fSpecificStorages);
592         TObjString *aCalibType=0;
593         AliCDBPath tmpPath("null/null/null");
594         AliCDBParam* aPar=0;
595         while((aCalibType = (TObjString*) iter.Next())){
596                 AliCDBPath calibTypePath(aCalibType->GetName());
597                 if(calibTypePath.Comprises(aPath)) {
598                         if(calibTypePath.Comprises(tmpPath)) continue;
599                         aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
600                         tmpPath.SetPath(calibTypePath.GetPath());
601                 }
602         }
603         return aPar;
604 }
605
606 //_____________________________________________________________________________
607 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path, Int_t runNumber,
608         Int_t version, Int_t subVersion) {
609 // get an AliCDBEntry object from the database
610
611         if(runNumber < 0){
612                 // RunNumber is not specified. Try with fRun
613                 if (fRun < 0){
614                         AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
615                         return NULL;
616                 }
617                 runNumber = fRun;
618         }
619
620         return Get(AliCDBId(path, runNumber, runNumber, version, subVersion));
621 }
622
623 //_____________________________________________________________________________
624 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path,
625         const AliCDBRunRange& runRange, Int_t version,
626         Int_t subVersion) {
627 // get an AliCDBEntry object from the database!
628
629         return Get(AliCDBId(path, runRange, version, subVersion));
630 }
631
632 //_____________________________________________________________________________
633 AliCDBEntry* AliCDBManager::Get(const AliCDBId& query) {
634 // get an AliCDBEntry object from the database
635         
636         // check if query's path and runRange are valid
637         // query is invalid also if version is not specified and subversion is!
638         if (!query.IsValid()) {
639                 AliError(Form("Invalid query: %s", query.ToString().Data()));
640                 return NULL;
641         }
642         
643         // query is not specified if path contains wildcard or run range= [-1,-1]
644         if (!query.IsSpecified()) {
645                 AliError(Form("Unspecified query: %s",
646                                 query.ToString().Data()));
647                 return NULL;
648         }
649
650         if(fLock && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun())) 
651                 AliFatal("Lock is ON: cannot use different run number than the internal one!");
652         
653         if(fCache && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun())) 
654                 AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
655
656         AliCDBEntry *entry=0;
657
658         // first look into map of cached objects
659         if(fCache && query.GetFirstRun() == fRun)
660                 entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
661
662         if(entry) {
663                 AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
664                 return entry;
665         }
666
667         if(!fDefaultStorage) {
668                 AliError("No storage set!");
669                 return NULL;
670         }
671         // Entry is not in cache -> retrieve it from CDB and cache it!!
672         AliCDBStorage *aStorage=0;
673         AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
674 //      Bool_t usedDefStorage=kTRUE;
675
676         if(aPar) {
677                 aStorage=GetStorage(aPar);
678                 TString str = aPar->GetURI();
679                 AliDebug(2,Form("Looking into storage: %s",str.Data()));
680 //              usedDefStorage=kFALSE;
681
682         } else {
683                 aStorage=GetDefaultStorage();
684                 AliDebug(2,"Looking into default storage");
685         }
686
687         entry = aStorage->Get(query);
688
689         if(entry && fCache && (query.GetFirstRun() == fRun)){
690                 CacheEntry(query.GetPath(), entry);
691         }
692
693         if(entry && !fIds->Contains(&entry->GetId())){
694                 fIds->Add(entry->GetId().Clone());
695         }
696
697
698         return entry;
699
700 }
701
702 //_____________________________________________________________________________
703 const char* AliCDBManager::GetURI(const char* path) {
704 // return the URI of the storage where to look for path
705
706         if(!IsDefaultStorageSet()) return 0;
707         
708         AliCDBParam *aPar=SelectSpecificStorage(path);
709
710         if(aPar) {
711                 return aPar->GetURI().Data();
712
713         } else {
714                 return GetDefaultStorage()->GetURI().Data();
715         }
716         
717         return 0;
718 }
719
720 //_____________________________________________________________________________
721 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path, Int_t runNumber,
722         Int_t version, Int_t subVersion) {
723 // get the AliCDBId of the valid object from the database (does not retrieve the object)
724 // User must delete returned object!
725
726         if(runNumber < 0){
727                 // RunNumber is not specified. Try with fRun
728                 if (fRun < 0){
729                         AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
730                         return NULL;
731                 }
732                 runNumber = fRun;
733         }
734
735         return GetId(AliCDBId(path, runNumber, runNumber, version, subVersion));
736 }
737
738 //_____________________________________________________________________________
739 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path,
740         const AliCDBRunRange& runRange, Int_t version,
741         Int_t subVersion) {
742 // get the AliCDBId of the valid object from the database (does not retrieve the object)
743 // User must delete returned object!
744
745         return GetId(AliCDBId(path, runRange, version, subVersion));
746 }
747
748 //_____________________________________________________________________________
749 AliCDBId* AliCDBManager::GetId(const AliCDBId& query) {
750 // get the AliCDBId of the valid object from the database (does not retrieve the object)
751 // User must delete returned object!
752
753         if(!fDefaultStorage) {
754                 AliError("No storage set!");
755                 return NULL;
756         }
757
758         // check if query's path and runRange are valid
759         // query is invalid also if version is not specified and subversion is!
760         if (!query.IsValid()) {
761                 AliError(Form("Invalid query: %s", query.ToString().Data()));
762                 return NULL;
763         }
764         
765         // query is not specified if path contains wildcard or run range= [-1,-1]
766         if (!query.IsSpecified()) {
767                 AliError(Form("Unspecified query: %s",
768                                 query.ToString().Data()));
769                 return NULL;
770         }
771
772         if(fCache && query.GetFirstRun() != fRun)
773                 AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
774
775         AliCDBEntry* entry = 0;
776
777         // first look into map of cached objects
778         if(fCache && query.GetFirstRun() == fRun)
779                 entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
780
781         if(entry) {
782                 AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
783                 return dynamic_cast<AliCDBId*> (entry->GetId().Clone());
784         }
785
786         // Entry is not in cache -> retrieve it from CDB and cache it!!
787         AliCDBStorage *aStorage=0;
788         AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
789
790         if(aPar) {
791                 aStorage=GetStorage(aPar);
792                 TString str = aPar->GetURI();
793                 AliDebug(2,Form("Looking into storage: %s",str.Data()));
794                 
795         } else {
796                 aStorage=GetDefaultStorage();
797                 AliDebug(2,"Looking into default storage");
798         }
799
800         return aStorage->GetId(query);
801
802 }
803
804 //_____________________________________________________________________________
805 TList* AliCDBManager::GetAll(const AliCDBPath& path, Int_t runNumber,
806         Int_t version, Int_t subVersion) {
807 // get multiple AliCDBEntry objects from the database
808
809         if(runNumber < 0){
810                 // RunNumber is not specified. Try with fRun
811                 if (fRun < 0){
812                         AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
813                         return NULL;
814                 }
815                 runNumber = fRun;
816         }
817
818         return GetAll(AliCDBId(path, runNumber, runNumber, version,     
819                         subVersion));
820 }
821
822 //_____________________________________________________________________________
823 TList* AliCDBManager::GetAll(const AliCDBPath& path,
824         const AliCDBRunRange& runRange, Int_t version, Int_t subVersion) {
825 // get multiple AliCDBEntry objects from the database
826
827         return GetAll(AliCDBId(path, runRange, version, subVersion));
828 }
829
830 //_____________________________________________________________________________
831 TList* AliCDBManager::GetAll(const AliCDBId& query) {
832 // get multiple AliCDBEntry objects from the database
833 // Warning: this method works correctly only for queries of the type "Detector/*"
834 //              and not for more specific queries e.g. "Detector/Calib/*" !
835 // Warning #2: Entries are cached, but GetAll will keep on retrieving objects from OCDB!
836 //              To get an object from cache use Get() function
837
838         if(!fDefaultStorage) {
839                 AliError("No storage set!");
840                 return NULL;
841         }
842
843         if (!query.IsValid()) {
844                 AliError(Form("Invalid query: %s", query.ToString().Data()));
845                 return NULL;
846         }
847
848         if((fSpecificStorages.GetEntries()>0) && query.GetPath().BeginsWith('*')){
849                 // if specific storages are active a query with "*" is ambiguous
850                 AliError("Query too generic in this context!");
851                 return NULL;
852         }
853
854         if (query.IsAnyRange()) {
855                 AliError(Form("Unspecified run or runrange: %s",
856                                 query.ToString().Data()));
857                 return NULL;
858         }
859
860         if(fLock && query.GetFirstRun() != fRun)
861                 AliFatal("Lock is ON: cannot use different run number than the internal one!");
862         
863         AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
864
865         AliCDBStorage *aStorage;
866         if(aPar) {
867                 aStorage=GetStorage(aPar);
868                 AliDebug(2,Form("Looking into storage: %s", aPar->GetURI().Data()));
869
870         } else {
871                 aStorage=GetDefaultStorage();
872                 AliDebug(2,"Looking into default storage");
873         }
874
875         TList *result = 0;
876         if(aStorage) result = aStorage->GetAll(query);
877         if(!result) return 0;
878
879        // loop on result to check whether entries should be re-queried with specific storages
880         if(fSpecificStorages.GetEntries()>0 && ! (fSpecificStorages.GetEntries() == 1 && aPar)) {
881                 AliInfo("Now look into all other specific storages...");
882
883                 TIter iter(result);
884                 AliCDBEntry* chkEntry=0;
885
886                 while((chkEntry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
887                         AliCDBId& chkId = chkEntry->GetId();
888                         AliDebug(2, Form("Checking id %s ", chkId.GetPath().Data()));
889                         AliCDBParam *chkPar=SelectSpecificStorage(chkId.GetPath());
890                         if (!chkPar || aPar == chkPar) continue;
891                         AliCDBStorage *chkStorage = GetStorage(chkPar);
892                         AliDebug(2, Form("Found specific storage! %s", chkPar->GetURI().Data()));
893
894                         AliCDBEntry *newEntry=0;
895                         chkId.SetRunRange(query.GetFirstRun(), query.GetLastRun());
896                         chkId.SetVersion(query.GetVersion());
897                         chkId.SetSubVersion(query.GetSubVersion());
898
899                         if(chkStorage) newEntry = chkStorage->Get(chkId);
900                         if(!newEntry) continue;
901
902                         // object is found in specific storage: replace entry in the result list!
903                         chkEntry->SetOwner(1);
904                         delete result->Remove(chkEntry);
905                         result->AddFirst(newEntry);
906                 }
907
908                 Int_t nEntries = result->GetEntries();
909                 AliInfo("After look into other specific storages, result list is:");
910                 for(int i=0; i<nEntries;i++){
911                         AliCDBEntry *entry = (AliCDBEntry*) result->At(i);
912                         AliInfo(Form("%s",entry->GetId().ToString().Data()));
913                 }
914         }
915
916         // caching entries
917         TIter iter(result);
918         AliCDBEntry* entry=0;
919         while((entry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
920
921                 if(!fIds->Contains(&entry->GetId())){
922                         fIds->Add(entry->GetId().Clone());
923                 }
924                 if(fCache && (query.GetFirstRun() == fRun)){
925                         CacheEntry(entry->GetId().GetPath(), entry);
926                 }
927         }
928
929
930         return result;
931 }
932
933 //_____________________________________________________________________________
934 Bool_t AliCDBManager::Put(TObject* object, AliCDBId& id, AliCDBMetaData* metaData, const DataType type){
935 // store an AliCDBEntry object into the database
936
937         if (object==0x0) {
938                 AliError("Null Entry! No storage will be done!");
939                 return kFALSE;
940         } 
941
942         AliCDBEntry anEntry(object, id, metaData);
943         return Put(&anEntry, type);
944
945 }
946
947
948 //_____________________________________________________________________________
949 Bool_t AliCDBManager::Put(AliCDBEntry* entry, DataType type){
950 // store an AliCDBEntry object into the database
951
952         if(type == kPrivate && !fDefaultStorage) {
953                 AliError("No storage set!");
954                 return kFALSE;
955         }
956
957         if (!entry){
958                 AliError("No entry!");
959                 return kFALSE;
960         }
961
962         if (entry->GetObject()==0x0){
963                 AliError("No valid object in CDB entry!");
964                 return kFALSE;
965         }
966
967         if (!entry->GetId().IsValid()) {
968                 AliError(Form("Invalid entry ID: %s", 
969                         entry->GetId().ToString().Data()));
970                 return kFALSE;
971         }       
972
973         if (!entry->GetId().IsSpecified()) {
974                 AliError(Form("Unspecified entry ID: %s", 
975                         entry->GetId().ToString().Data()));
976                 return kFALSE;
977         }
978
979         AliCDBId id = entry->GetId();
980         AliCDBParam *aPar = SelectSpecificStorage(id.GetPath());
981
982         AliCDBStorage *aStorage=0;
983         
984         if(aPar) {
985                 aStorage=GetStorage(aPar);
986         } else {
987                 switch(type){
988                         case kCondition:
989                                 aStorage = GetStorage(fCondParam);
990                                 break;
991                         case kReference:
992                                 aStorage = GetStorage(fRefParam);
993                                 break;
994                         case kPrivate:
995                                 aStorage = GetDefaultStorage();
996                                 break;
997                 }
998         }
999
1000         AliDebug(2,Form("Storing object into storage: %s", aStorage->GetURI().Data()));
1001
1002         Bool_t result = aStorage->Put(entry, type);
1003
1004         if(fRun >= 0) QueryCDB();
1005
1006         return result;
1007
1008
1009 }
1010
1011 //_____________________________________________________________________________
1012 void AliCDBManager::CacheEntry(const char* path, AliCDBEntry* entry)
1013 {
1014 // cache AliCDBEntry. Cache is valid until run number is changed.
1015
1016         AliCDBEntry *chkEntry = dynamic_cast<AliCDBEntry*> (fEntryCache.GetValue(path));
1017
1018         if(chkEntry) {
1019                 AliDebug(2, Form("Object %s already in cache !!", path));
1020                 return;
1021         } else {
1022                 AliDebug(2,Form("Caching entry %s", path));
1023         }
1024
1025         fEntryCache.Add(new TObjString(path), entry);
1026         AliDebug(2,Form("Cache entries: %d", fEntryCache.GetEntries()));
1027
1028 }
1029
1030 //_____________________________________________________________________________
1031 void AliCDBManager::Print(Option_t* /*option*/) const
1032 {
1033 // Print list of active storages and their URIs
1034
1035         TString output=Form("Run number = %d; ",fRun);
1036         output += "Cache is ";
1037         if(!fCache) output += "NOT ";
1038         output += Form("ACTIVE; Number of active storages: %d\n",fActiveStorages.GetEntries());
1039
1040         if(fDefaultStorage) {
1041                 output += Form("\t*** Default Storage URI: \"%s\"\n",fDefaultStorage->GetURI().Data());
1042 //              AliInfo(output.Data());
1043         }
1044         if(fSpecificStorages.GetEntries()>0) {
1045                 TIter iter(fSpecificStorages.GetTable());
1046                 TPair *aPair=0;
1047                 Int_t i=1;
1048                 while((aPair = (TPair*) iter.Next())){
1049                         output += Form("\t*** Specific storage %d: Path \"%s\" -> URI \"%s\"\n",
1050                                 i++, ((TObjString*) aPair->Key())->GetName(),
1051                                 ((AliCDBParam*) aPair->Value())->GetURI().Data());
1052                 }
1053         }
1054         if(fDrainStorage) {
1055                 output += Form("*** Drain Storage URI: %s\n",fDrainStorage->GetURI().Data());
1056         }
1057         AliInfo(output.Data());
1058 }
1059
1060 //_____________________________________________________________________________
1061 void AliCDBManager::SetRun(Int_t run)
1062 {
1063 // Sets current run number.
1064 // When the run number changes the caching is cleared.
1065         
1066         if(fRun == run)
1067                 return;
1068   
1069         if(fLock && fRun >= 0) {
1070                 AliFatal("Lock is ON, cannot reset run number!");
1071         }       
1072                 
1073         fRun = run;
1074         if(fRaw){
1075                 // here the LHCPeriod xml file is parsed; the string containing the correct period is returned; the default storage is set
1076                 if (fStartRunLHCPeriod <= run && fEndRunLHCPeriod >= run){
1077                         AliInfo("LHCPeriod alien folder for current run already in memory");
1078                 }else{
1079                         SetDefaultStorageFromRun(run);
1080                         if(fEntryCache.GetEntries()!=0) ClearCache();
1081                         return;
1082                 }
1083         }
1084         ClearCache();
1085         QueryCDB();
1086 }
1087
1088 //_____________________________________________________________________________
1089 void AliCDBManager::ClearCache(){
1090 // clear AliCDBEntry cache
1091
1092         AliDebug(2, Form("Cache entries to be deleted: %d",fEntryCache.GetEntries()));
1093         
1094         /*
1095         // To clean entries one by one
1096         TIter iter(fEntryCache.GetTable());
1097         TPair* pair=0;
1098         while((pair= dynamic_cast<TPair*> (iter.Next()))){
1099         
1100                 TObjString* key = dynamic_cast<TObjString*> (pair->Key());
1101                 AliCDBEntry* entry = dynamic_cast<AliCDBEntry*> (pair->Value());
1102                 AliDebug(2, Form("Deleting entry: %s", key->GetName()));
1103                 if (entry) delete entry;
1104                 delete fEntryCache.Remove(key);
1105         }
1106         */
1107         fEntryCache.DeleteAll();
1108         AliDebug(2, Form("After deleting - Cache entries: %d",fEntryCache.GetEntries()));
1109 }
1110
1111 //_____________________________________________________________________________
1112 void AliCDBManager::UnloadFromCache(const char* path){
1113 // unload cached object
1114
1115         if(!fActiveStorages.GetEntries()) {
1116                 AliDebug(2, Form("No active storages. Object \"%s\" is not unloaded from cache", path));
1117                 return;
1118         }
1119
1120         AliCDBPath queryPath(path);
1121         if(!queryPath.IsValid()) return;
1122
1123         if(!queryPath.IsWildcard()) { // path is not wildcard, get it directly from the cache and unload it!
1124                 if(fEntryCache.Contains(path)){
1125                         AliDebug(2, Form("Unloading object \"%s\" from cache", path));
1126                         TObjString pathStr(path);
1127                         delete fEntryCache.Remove(&pathStr);
1128                 } else {
1129                   AliErrorF("Cache does not contain object \"%s\"!", path);
1130                 }
1131                 AliDebugF(2, "Cache entries: %d",fEntryCache.GetEntries());
1132                 return;
1133         }
1134
1135         // path is wildcard: loop on the cache and unload all comprised objects!
1136         TIter iter(fEntryCache.GetTable());
1137         TPair* pair = 0;
1138
1139         while((pair = dynamic_cast<TPair*> (iter.Next()))){
1140                 AliCDBPath entryPath = pair->Key()->GetName();
1141                 if(queryPath.Comprises(entryPath)) {
1142                         AliDebug(2, Form("Unloading object \"%s\" from cache", entryPath.GetPath().Data()));
1143                         TObjString pathStr(entryPath.GetPath().Data());
1144                         delete fEntryCache.Remove(&pathStr);
1145                 }
1146         }
1147         AliDebug(2,Form("Cache entries: %d",fEntryCache.GetEntries()));
1148 }
1149
1150 //_____________________________________________________________________________
1151 void AliCDBManager::DestroyActiveStorages() {
1152 // delete list of active storages
1153
1154         fActiveStorages.DeleteAll();
1155         fSpecificStorages.DeleteAll();
1156 }
1157
1158 //_____________________________________________________________________________
1159 void AliCDBManager::DestroyActiveStorage(AliCDBStorage* /*storage*/) {
1160 // destroys active storage
1161
1162 /*
1163         TIter iter(fActiveStorages.GetTable());
1164         TPair* aPair;
1165         while ((aPair = (TPair*) iter.Next())) {
1166                 if(storage == (AliCDBStorage*) aPair->Value())
1167                         delete fActiveStorages.Remove(aPair->Key());
1168                         storage->Delete(); storage=0x0;
1169         }
1170 */
1171
1172 }
1173
1174 //_____________________________________________________________________________
1175 void AliCDBManager::QueryCDB() {
1176 // query default and specific storages for files valid for fRun. Every storage loads the Ids into its list.
1177
1178         if (fRun < 0){
1179                 AliError("Run number not yet set! Use AliCDBManager::SetRun.");
1180         return;
1181         }
1182         if (!fDefaultStorage){
1183                 AliError("Default storage is not set! Use AliCDBManager::SetDefaultStorage");
1184         return;
1185         }
1186         if(fDefaultStorage->GetType() == "alien"){
1187                 fDefaultStorage->QueryCDB(fRun);
1188         } else {
1189                 AliDebug(2,"Skipping query for valid files, it used only in grid...");
1190         }
1191
1192         TIter iter(&fSpecificStorages);
1193         TObjString *aCalibType=0;
1194         AliCDBParam* aPar=0;
1195         while((aCalibType = dynamic_cast<TObjString*> (iter.Next()))){
1196                 aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
1197                 if(aPar) {
1198                         AliDebug(2,Form("Querying specific storage %s",aCalibType->GetName()));
1199                         AliCDBStorage *aStorage = GetStorage(aPar);
1200                         if(aStorage->GetType() == "alien"){
1201                                 aStorage->QueryCDB(fRun,aCalibType->GetName());
1202                         } else {
1203                                 AliDebug(2,
1204                                         "Skipping query for valid files, it is used only in grid...");
1205                         }
1206                 }
1207         }
1208 }
1209
1210 //______________________________________________________________________________________________
1211 const char* AliCDBManager::GetDataTypeName(DataType type)
1212 {
1213   // returns the name (string) of the data type
1214
1215       switch (type){
1216             case kCondition: return "Conditions";
1217             case kReference: return "Reference";
1218             case kPrivate: return "Private";
1219      }
1220      return 0;
1221
1222 }
1223
1224 //______________________________________________________________________________________________
1225 void AliCDBManager::InitShortLived()
1226 {
1227   // Init the list of short-lived objects
1228   // currently disabled
1229
1230         fShortLived=0x0;
1231
1232 //      fShortLived = new TList();
1233 //      fShortLived->SetOwner(1);
1234 //
1235 //      fShortLived->Add(new TObjString("EMCAL/Calib/Data"));
1236 // 
1237 //      fShortLived->Add(new TObjString("HMPID/Calib/Nmean"));
1238 //      fShortLived->Add(new TObjString("HMPID/Calib/Qthre"));
1239 // 
1240 //      fShortLived->Add(new TObjString("ITS/Calib/CalibSPD"));
1241 // 
1242 //      fShortLived->Add(new TObjString("MUON/Calib/Gains"));
1243 //      fShortLived->Add(new TObjString("MUON/Calib/HV"));
1244 //      fShortLived->Add(new TObjString("MUON/Calib/Pedestals"));
1245 // 
1246 //      fShortLived->Add(new TObjString("PHOS/Calib/CpvGainPedestals"));
1247 //      fShortLived->Add(new TObjString("PHOS/Calib/EmcGainPedestals"));
1248 // 
1249 //      fShortLived->Add(new TObjString("PMD/Calib/Data"));
1250 // 
1251 //      fShortLived->Add(new TObjString("TRD/Calib/ChamberGainFactor"));
1252 //      fShortLived->Add(new TObjString("TRD/Calib/LocalGainFactor"));
1253 //      fShortLived->Add(new TObjString("TRD/Calib/ChamberT0"));
1254 //      fShortLived->Add(new TObjString("TRD/Calib/LocalT0"));
1255 //      fShortLived->Add(new TObjString("TRD/Calib/ChamberVdrift"));
1256 //      fShortLived->Add(new TObjString("TRD/Calib/LocalVdrift"));
1257 // 
1258 //      fShortLived->Add(new TObjString("ZDC/Calib/Data"));
1259
1260 }
1261
1262 //______________________________________________________________________________________________
1263 Bool_t AliCDBManager::IsShortLived(const char* path)
1264 {
1265   // returns the name (string) of the data type
1266
1267         if(!fShortLived) return kFALSE;
1268
1269         AliCDBPath aPath(path);
1270         if(!aPath.IsValid()){
1271                 AliError(Form("Not a valid path: %s", path));
1272                 return kFALSE;
1273         }
1274
1275         return fShortLived->Contains(path);
1276
1277 }
1278
1279 //______________________________________________________________________________________________
1280 ULong_t AliCDBManager::SetLock(Bool_t lock, ULong_t key){
1281   // To lock/unlock user must provide the key. A new key is provided after
1282   // each successful lock. User should always backup the returned key and
1283   // use it on next access.
1284   if (fLock == lock) return 0;  // nothing to be done
1285   if (lock) {
1286     // User wants to lock - check his identity
1287     if (fKey) {
1288       // Lock has a user - check his key
1289       if (fKey != key) {
1290         AliFatal("Wrong key provided to lock CDB. Please remove CDB lock access from your code !");
1291         return 0;
1292       }  
1293     }  
1294     // Provide new key 
1295     fKey = gSystem->Now();
1296     fLock = kTRUE;
1297     return fKey;
1298   }
1299   // User wants to unlock - check the provided key
1300   if (key != fKey) {
1301     AliFatal("Lock is ON: wrong key provided");
1302     return 0;
1303   }  
1304   fLock = kFALSE;
1305   return key;  
1306 }
1307
1308 ///////////////////////////////////////////////////////////
1309 // AliCDBManager Parameter class                         //
1310 // interface to specific AliCDBParameter class           //
1311 // (AliCDBGridParam, AliCDBLocalParam, AliCDBDumpParam)  //
1312 ///////////////////////////////////////////////////////////
1313
1314 AliCDBParam::AliCDBParam():
1315   fType(),
1316   fURI()
1317 {
1318 // constructor
1319
1320 }
1321
1322 //_____________________________________________________________________________
1323 AliCDBParam::~AliCDBParam() {
1324 // destructor
1325
1326 }
1327