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