e9e55f17a5edae1a876b259cfcceb9c28da7d82d
[u/mrichter/AliRoot.git] / STEER / CDB / 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 <stdlib.h>
22 #include <fstream>
23
24 #include "AliCDBManager.h"
25 #include "AliCDBStorage.h"
26 #include "AliLog.h"
27 #include "AliCDBDump.h"
28 #include "AliCDBLocal.h"
29 #include "AliCDBGrid.h"
30 #include "AliCDBEntry.h"
31 #include "AliCDBHandler.h"
32
33 #include <TObjString.h>
34 #include <TSAXParser.h>
35 #include <TFile.h>
36 #include <TKey.h>
37 #include <TUUID.h>
38 #include <TGrid.h>
39 #include "TMessage.h"
40 #include "TObject.h"
41 #include "TRegexp.h"
42
43 ClassImp(AliCDBParam)
44
45 ClassImp(AliCDBManager)
46
47 //TODO OCDB and Reference folder should not be fully hardcoded but built from run number (or year/LHC period)
48 TString AliCDBManager::fgkCondUri("alien://folder=/alice/cern.ch/user/a/aliprod/testCDB/CDB?user=aliprod");
49 TString AliCDBManager::fgkRefUri("alien://folder=/alice/cern.ch/user/a/aliprod/testCDB/Reference?user=aliprod");
50 TString AliCDBManager::fgkMCIdealStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Ideal");
51 TString AliCDBManager::fgkMCFullStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Full");
52 TString AliCDBManager::fgkMCResidualStorage("alien://folder=/alice/simulation/2008/v4-15-Release/Residual");
53 TString AliCDBManager::fgkOCDBFolderXMLfile("alien:///alice/data/OCDBFoldervsRunRange.xml");
54 AliCDBManager* AliCDBManager::fgInstance = 0x0;
55
56 //_____________________________________________________________________________
57 AliCDBManager* AliCDBManager::Instance(TMap *entryCache, Int_t run) {
58 // returns AliCDBManager instance (singleton)
59
60   if (!fgInstance) {
61     fgInstance = new AliCDBManager();
62     if (!entryCache)
63       fgInstance->Init();
64     else
65       fgInstance->InitFromCache(entryCache,run);
66   }
67
68   return fgInstance;
69 }
70
71 //_____________________________________________________________________________
72 void AliCDBManager::Init() {
73 // factory registering
74
75   RegisterFactory(new AliCDBDumpFactory());
76   RegisterFactory(new AliCDBLocalFactory());
77   // AliCDBGridFactory is registered only if AliEn libraries are enabled in Root
78   if(!gSystem->Exec("root-config --has-alien 2>/dev/null |grep yes 2>&1 > /dev/null")){ // returns 0 if yes
79     AliInfo("AliEn classes enabled in Root. AliCDBGrid factory registered.");
80     RegisterFactory(new AliCDBGridFactory());
81     fCondParam = CreateParameter(fgkCondUri);
82     fRefParam = CreateParameter(fgkRefUri);
83   }
84
85   InitShortLived();
86 }
87
88 //_____________________________________________________________________________
89 void AliCDBManager::InitFromCache(TMap *entryCache, Int_t run) {
90 // initialize manager from existing cache
91 // used on the slaves in case of parallel reconstruction
92   SetRun(run);
93
94   TIter iter(entryCache->GetTable());
95   TPair* pair = 0;
96
97   while((pair = dynamic_cast<TPair*> (iter.Next()))){
98     fEntryCache.Add(pair->Key(),pair->Value());
99   }
100   // fEntry is the new owner of the cache
101   fEntryCache.SetOwnerKeyValue(kTRUE,kTRUE);
102   entryCache->SetOwnerKeyValue(kFALSE,kFALSE);
103   AliInfo(Form("%d cache entries have been loaded",fEntryCache.GetEntries()));
104 }
105
106 //_____________________________________________________________________________
107 void  AliCDBManager::DumpToSnapshotFile(const char* snapshotFileName, Bool_t singleKeys){
108 //
109 // dump the entries map and the ids list to
110 // the output file
111
112   // open the file
113   TFile *f = TFile::Open(snapshotFileName,"RECREATE");
114   if (!f || f->IsZombie()){
115     AliError(Form("Cannot open file %s",snapshotFileName));
116     return;
117   }
118
119   AliInfo(Form("Dumping entriesMap (entries'cache) with %d entries!\n", fEntryCache.GetEntries()));
120   AliInfo(Form("Dumping entriesList with %d entries!\n", fIds->GetEntries()));
121
122   f->cd();
123
124   if(singleKeys){
125     f->WriteObject(&fEntryCache,"CDBentriesMap");
126     f->WriteObject(fIds,"CDBidsList");
127   }else{
128     // We write the entries one by one named by their calibration path
129     /*
130        fEntryCache.Write("CDBentriesMap");
131        fIds->Write("CDBidsList");
132        */
133     TIter iter(fEntryCache.GetTable());
134     TPair* pair = 0;
135     while((pair = dynamic_cast<TPair*> (iter.Next()))){
136       TObjString *os = dynamic_cast<TObjString*>(pair->Key());
137       if (!os) continue;
138       TString path = os->GetString();
139       AliCDBEntry *entry = dynamic_cast<AliCDBEntry*>(pair->Value());
140       if (!entry) continue;
141       path.ReplaceAll("/","*");
142       entry->Write(path.Data());
143     }
144   }
145   f->Close();
146   delete f;
147
148   exit(0);
149 }
150
151 //_____________________________________________________________________________
152 Bool_t AliCDBManager::InitFromSnapshot(const char* snapshotFileName, Bool_t overwrite){
153 // initialize manager from a CDB snapshot, that is add the entries
154 // to the entries map and the ids to the ids list taking them from
155 // the map and the list found in the input file
156
157   // if the manager is locked it cannot initialize from a snapshot
158   if(fLock) {
159     AliError("Being locked I cannot initialize from the snapshot!");
160     return kFALSE;
161   }     
162
163   // open the file
164   TString snapshotFile(snapshotFileName);
165   if(snapshotFile.BeginsWith("alien://")){
166     if(!gGrid) {
167       TGrid::Connect("alien://","");
168       if(!gGrid) {
169         AliError("Connection to alien failed!");
170         return kFALSE;
171       }
172     }
173   }
174
175   TFile *f = TFile::Open(snapshotFileName);
176   if (!f || f->IsZombie()){
177     AliError(Form("Cannot open file %s",snapshotFileName));
178     return kFALSE;
179   }
180
181   // retrieve entries' map from snapshot file
182   TMap *entriesMap = 0;
183   TIter next(f->GetListOfKeys());
184   TKey *key;
185   while ((key = (TKey*)next())) {
186     if (strcmp(key->GetClassName(),"TMap") != 0) continue;
187     entriesMap = (TMap*)key->ReadObj();
188     break;
189   }
190   if (!entriesMap || entriesMap->GetEntries()==0){
191     AliError("Cannot get valid map of CDB entries from snapshot file");
192     return kFALSE;
193   }
194
195   // retrieve ids' list from snapshot file
196   TList *idsList = 0;
197   TIter nextKey(f->GetListOfKeys());
198   TKey *keyN;
199   while ((keyN = (TKey*)nextKey())) {
200     if (strcmp(keyN->GetClassName(),"TList") != 0) continue;
201     idsList = (TList*)keyN->ReadObj();
202     break;
203   }
204   if (!idsList || idsList->GetEntries()==0){
205     AliError("Cannot get valid list of CDB entries from snapshot file");
206     return kFALSE;
207   }
208
209   // Add each (entry,id) from the snapshot to the memory: entry to the cache, id to the list of ids.
210   // If "overwrite" is false: add the entry to the cache and its id to the list of ids
211   // only if neither of them is already there.
212   // If "overwrite" is true: write the snapshot entry,id in any case. If something
213   // was already there for that calibration type, remove it and issue a warning
214   TIter iterObj(entriesMap->GetTable());
215   TPair* pair = 0;
216   Int_t nAdded=0;
217   while((pair = dynamic_cast<TPair*> (iterObj.Next()))){
218     TObjString* os = (TObjString*) pair->Key();
219     TString path = os->GetString();
220     TIter iterId(idsList);
221     AliCDBId* id=0;
222     AliCDBId* correspondingId=0;
223     while((id = dynamic_cast<AliCDBId*> (iterId.Next()))){
224       TString idpath(id->GetPath());
225       if(idpath==path){
226         correspondingId=id;
227         break;
228       }
229     }
230     if(!correspondingId){
231       AliError(Form("id for \"%s\" not found in the snapshot (while entry was). This entry is skipped!",path.Data()));
232       break;
233     }
234     Bool_t cached = fEntryCache.Contains(path.Data());
235     Bool_t registeredId = kFALSE;
236     TIter iter(fIds);
237     AliCDBId *idT = 0;
238     while((idT = dynamic_cast<AliCDBId*> (iter.Next()))){
239       if(idT->GetPath()==path){
240         registeredId = kTRUE;
241         break;
242       }
243     }
244
245     if(overwrite){
246       if(cached || registeredId){
247         AliWarning(Form("An entry was already cached for \"%s\". Removing it before caching from snapshot",path.Data()));
248         UnloadFromCache(path.Data());
249       }
250       fEntryCache.Add(pair->Key(),pair->Value());
251       fIds->Add(id);
252       nAdded++;
253     }else{
254       if(cached || registeredId){
255         AliWarning(Form("An entry was already cached for \"%s\". Not adding this object from snapshot",path.Data()));
256       }else{
257         fEntryCache.Add(pair->Key(),pair->Value());
258         fIds->Add(id);
259         nAdded++;
260       }
261     }
262   }
263
264   // fEntry is the new owner of the cache
265   fEntryCache.SetOwnerKeyValue(kTRUE,kTRUE);
266   entriesMap->SetOwnerKeyValue(kFALSE,kFALSE);
267   fIds->SetOwner(kTRUE);
268   idsList->SetOwner(kFALSE);
269   AliInfo(Form("%d new (entry,id) cached. Total number %d",nAdded,fEntryCache.GetEntries()));
270
271   f->Close();
272   delete f;
273
274   return kTRUE;
275 }
276
277 //_____________________________________________________________________________
278 void AliCDBManager::Destroy() {
279 // delete ALCDBManager instance and active storages
280
281   if (fgInstance) {
282     //fgInstance->Delete();
283     delete fgInstance;
284     fgInstance = 0x0;
285   }
286 }
287
288 //_____________________________________________________________________________
289 AliCDBManager::AliCDBManager():
290   TObject(),
291   fFactories(),
292   fActiveStorages(),
293   fSpecificStorages(),
294   fEntryCache(),
295   fIds(0),
296   fStorageMap(0),
297   fShortLived(0),
298   fDefaultStorage(NULL),
299   fDrainStorage(NULL),
300   fCondParam(0),
301   fRefParam(0),
302   fRun(-1),
303   fCache(kTRUE),
304   fLock(kFALSE),
305   fSnapshotMode(kFALSE),
306   fSnapshotFile(0),
307   fRaw(kFALSE),
308   fCvmfsOcdb(""),
309   fStartRunLHCPeriod(-1),
310   fEndRunLHCPeriod(-1),
311   fLHCPeriod(""),
312   fKey(0)
313 {
314   // default constuctor
315   fFactories.SetOwner(1);
316   fActiveStorages.SetOwner(1);
317   fSpecificStorages.SetOwner(1);
318   fEntryCache.SetName("CDBEntryCache");
319   fEntryCache.SetOwnerKeyValue(kTRUE,kTRUE);
320
321   fStorageMap = new TMap();
322   fStorageMap->SetOwner(1);
323   fIds = new TList();
324   fIds->SetOwner(1);
325 }
326
327 //_____________________________________________________________________________
328 AliCDBManager::~AliCDBManager() {
329 // destructor
330   ClearCache();
331   DestroyActiveStorages();
332   fFactories.Delete();
333   fDrainStorage = 0x0;
334   fDefaultStorage = 0x0;
335   delete fStorageMap; fStorageMap = 0;
336   delete fIds; fIds = 0;
337   delete fCondParam;
338   delete fRefParam;
339   delete fShortLived; fShortLived = 0x0;
340   //fSnapshotCache = 0;
341   //fSnapshotIdsList = 0;
342   if(fSnapshotMode){
343     fSnapshotFile->Close();
344     fSnapshotFile = 0;
345   }
346 }
347
348 //_____________________________________________________________________________
349 void AliCDBManager::PutActiveStorage(AliCDBParam* param, AliCDBStorage* storage){
350 // put a storage object into the list of active storages
351
352   fActiveStorages.Add(param, storage);
353   AliDebug(1, Form("Active storages: %d", fActiveStorages.GetEntries()));
354 }
355
356 //_____________________________________________________________________________
357 void AliCDBManager::RegisterFactory(AliCDBStorageFactory* factory) {
358 // add a storage factory to the list of registerd factories
359
360   if (!fFactories.Contains(factory)) {
361     fFactories.Add(factory);
362   }
363 }
364
365 //_____________________________________________________________________________
366 Bool_t AliCDBManager::HasStorage(const char* dbString) const {
367 // check if dbString is a URI valid for one of the registered factories
368
369   TIter iter(&fFactories);
370
371   AliCDBStorageFactory* factory=0;
372   while ((factory = (AliCDBStorageFactory*) iter.Next())) {
373
374     if (factory->Validate(dbString)) {
375       return kTRUE;
376     }
377   }
378
379   return kFALSE;
380 }
381
382 //_____________________________________________________________________________
383 AliCDBParam* AliCDBManager::CreateParameter(const char* dbString) const {
384 // create AliCDBParam object from URI string
385
386   TString uriString(dbString);
387
388   if (! fCvmfsOcdb.IsNull()) {
389     AlienToCvmfsUri(uriString);
390   }
391
392   TIter iter(&fFactories);
393
394   AliCDBStorageFactory* factory=0;
395   while ((factory = (AliCDBStorageFactory*) iter.Next())) {
396     //AliCDBParam* param = factory->CreateParameter(dbString);
397     AliCDBParam* param = factory->CreateParameter(uriString);
398     if(param) return param;
399   }
400
401   return NULL;
402 }
403
404 //_____________________________________________________________________________
405 void AliCDBManager::AlienToCvmfsUri(TString& uriString) const {
406 // convert alien storage uri to local:///cvmfs storage uri (called when OCDB_PATH is set)
407
408   if (! uriString.BeginsWith("alien://") && !fCvmfsOcdb.IsNull())
409     AliFatal("Cannot set local://cvmfs storage for a non alien uri");
410
411   TObjArray *arr = uriString.Tokenize('?');
412   TIter iter(arr);
413   TObjString *str = 0;
414   TString entryKey = "";
415   TString entryValue  = "";
416   TString newUriString = "";
417   while((str = (TObjString*) iter.Next())){
418     TString entry(str->String());
419     Int_t indeq = entry.Index('=');
420     entryKey = entry(0, indeq+1);
421     entryValue = entry(indeq+1, entry.Length()-indeq);
422
423     if ( entryKey.Contains("folder", TString::kIgnoreCase) )
424     {
425
426       TRegexp re_RawFolder("^/alice/data/20[0-9]+/OCDB");
427       TRegexp re_MCFolder("^/alice/simulation/2008/v4-15-Release");
428       TString rawFolder = entryValue(re_RawFolder);
429       TString mcFolder = entryValue(re_MCFolder);
430       if ( !rawFolder.IsNull() ){
431         entryValue.Replace(0, 6, "/cvmfs/alice.cern.ch/calibration");
432         //entryValue.Replace(entryValue.Length()-4, entryValue.Length(), "");
433       } else if ( !mcFolder.IsNull() ){
434         entryValue.Replace(0,36,"/cvmfs/alice.cern.ch/calibration/MC");
435       } else {
436         AliFatal(Form("Environment variable for cvmfs OCDB folder set for an invalid OCDB storage:\n   %s", entryValue.Data()));
437       }
438     } else {
439       newUriString += entryKey;
440     }
441     newUriString += entryValue;
442     newUriString += '?';
443   }
444   newUriString.Prepend("local://");
445   newUriString.Remove(TString::kTrailing, '?');
446   uriString = newUriString;
447 }
448
449 //_____________________________________________________________________________
450 AliCDBStorage* AliCDBManager::GetStorage(const char* dbString) {
451 // get storage object from URI string
452
453   // Check environment variable OCDB_PATH. It is set in case the user (job) expects
454   // to find in the local /cvmfs the required OCDB tag. The OCDB_PATH variable
455   // contains the path to the directory in /cvmfs/ which is an AliRoot tag based snapshot
456   // of the AliEn file catalogue. The directory has to contain:
457   // 1) catalogue/20??.list.gz gzipped text files listing the OCDB files (seen by that AliRoot tag)
458   // 2) bin/getOCDBperRun.sh   (shell+awk) script extracting from 1) the list
459   // of valid files for the given run.
460
461   AliCDBParam* param = CreateParameter(dbString);
462   if (!param) {
463     AliError(Form("Failed to activate requested storage! Check URI: %s", dbString));
464     return NULL;
465   }
466
467   AliCDBStorage* aStorage = GetStorage(param);
468
469   delete param;
470   return aStorage;
471 }
472
473 //_____________________________________________________________________________
474 AliCDBStorage* AliCDBManager::GetStorage(const AliCDBParam* param) {
475 // get storage object from AliCDBParam object
476
477   // if the list of active storages already contains
478   // the requested storage, return it
479   AliCDBStorage* aStorage = GetActiveStorage(param);
480   if (aStorage) {
481     return aStorage;
482   }
483
484   // if lock is ON, cannot activate more storages!
485   if(fLock) {
486     if (fDefaultStorage) {
487       AliFatal("Lock is ON, and default storage is already set: "
488           "cannot reset it or activate more storages!");
489     }
490   }     
491
492   // loop on the list of registered factories
493   TIter iter(&fFactories);
494   AliCDBStorageFactory* factory=0;
495   while ((factory = (AliCDBStorageFactory*) iter.Next())) {
496
497     // each factory tries to create its storage from the parameter
498     aStorage = factory->Create(param);
499     if (aStorage) {
500       PutActiveStorage(param->CloneParam(), aStorage);
501       aStorage->SetURI(param->GetURI());
502       if(fRun >= 0) {
503         if( aStorage->GetType() == "alien" || aStorage->GetType() == "local" )
504           aStorage->QueryCDB(fRun);
505       }
506       return aStorage;
507     }
508   }
509
510   AliError(Form("Failed to activate requested storage! Check URI: %s", param->GetURI().Data()));
511
512   return NULL;
513 }
514
515 //_____________________________________________________________________________
516 AliCDBStorage* AliCDBManager::GetActiveStorage(const AliCDBParam* param) {
517 // get a storage object from the list of active storages
518
519   return dynamic_cast<AliCDBStorage*> (fActiveStorages.GetValue(param));
520 }
521
522 //_____________________________________________________________________________
523 TList* AliCDBManager::GetActiveStorages() {
524 // return list of active storages
525 // user has responsibility to delete returned object
526
527   TList* result = new TList();
528
529   TIter iter(fActiveStorages.GetTable());
530   TPair* aPair=0;
531   while ((aPair = (TPair*) iter.Next())) {
532     result->Add(aPair->Value());
533   }
534
535   return result;
536 }
537
538 //_____________________________________________________________________________
539 void AliCDBManager::SetDrain(const char* dbString) {
540 // set drain storage from URI string
541
542   fDrainStorage = GetStorage(dbString); 
543 }
544
545 //_____________________________________________________________________________
546 void AliCDBManager::SetDrain(const AliCDBParam* param) {
547 // set drain storage from AliCDBParam
548
549   fDrainStorage = GetStorage(param);
550 }
551
552 //_____________________________________________________________________________
553 void AliCDBManager::SetDrain(AliCDBStorage* storage) {
554 // set drain storage from another active storage
555
556   fDrainStorage = storage;
557 }
558
559 //_____________________________________________________________________________
560 Bool_t AliCDBManager::Drain(AliCDBEntry *entry) {
561 // drain retrieved object to drain storage
562
563   AliDebug(2, "Draining into drain storage...");
564   return fDrainStorage->Put(entry);
565 }
566
567 //____________________________________________________________________________
568 void AliCDBManager::SetDefaultStorage(const char* storageUri) {
569 // sets default storage from URI string
570
571   // if in the cvmfs case (triggered by environment variable) check for path validity
572   // and modify Uri if it is "raw://"
573   TString cvmfsOcdb(gSystem->Getenv("OCDB_PATH"));
574   if (! cvmfsOcdb.IsNull()){
575     fCvmfsOcdb = cvmfsOcdb;
576     ValidateCvmfsCase();
577   }
578
579   // checking whether we are in the raw case
580   TString uriTemp(storageUri);
581   if (uriTemp == "raw://") {
582     fRaw = kTRUE; // read then by SetRun to check if the method has to be called again with expanded uri
583     AliInfo("Setting the run-number will set the corresponding OCDB for raw data reconstruction.");
584     return;
585   }
586
587   AliCDBStorage* bckStorage = fDefaultStorage;
588
589   fDefaultStorage = GetStorage(storageUri);
590
591   if(!fDefaultStorage) return;
592
593   if(bckStorage && (fDefaultStorage != bckStorage)){
594     AliWarning("Existing default storage replaced: clearing cache!");
595     ClearCache();
596   }
597
598   if (fStorageMap->Contains("default")) {
599     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
600   }
601   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
602 }
603
604 //_____________________________________________________________________________
605 void AliCDBManager::SetDefaultStorage(const AliCDBParam* param) {
606 // set default storage from AliCDBParam object
607
608   AliCDBStorage* bckStorage = fDefaultStorage;
609
610   fDefaultStorage = GetStorage(param);
611
612   if(!fDefaultStorage) return;
613
614   if(bckStorage && (fDefaultStorage != bckStorage)){
615     AliWarning("Existing default storage replaced: clearing cache!");
616     ClearCache();
617   }
618
619   if (fStorageMap->Contains("default")) {
620     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
621   }
622   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
623 }
624
625 //_____________________________________________________________________________
626 void AliCDBManager::SetDefaultStorage(AliCDBStorage* storage) {
627 // set default storage from another active storage
628
629   // if lock is ON, cannot activate more storages!
630   if(fLock) {
631     if (fDefaultStorage) {
632       AliFatal("Lock is ON, and default storage is already set: "
633           "cannot reset it or activate more storages!");
634     }
635   }     
636
637   if (!storage) {
638     UnsetDefaultStorage();
639     return;
640   }
641
642   AliCDBStorage* bckStorage = fDefaultStorage;
643
644   fDefaultStorage = storage;
645
646   if(bckStorage && (fDefaultStorage != bckStorage)){
647     AliWarning("Existing default storage replaced: clearing cache!");
648     ClearCache();
649   }
650
651   if (fStorageMap->Contains("default")) {
652     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
653   }
654   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
655 }
656
657 //_____________________________________________________________________________
658 void AliCDBManager::SetDefaultStorage(const char* mcString, const char* simType) {
659 // sets default storage for MC data
660 // mcString MUST be "MC",
661 // simType can be "Ideal","Residual","Full"
662
663   TString strmcString(mcString);
664   TString strsimType(simType);
665   TString dbString;
666   if (strmcString != "MC"){
667     AliFatal("Method requires first string to be MC!");
668   }
669   else {
670     if (strsimType == "Ideal"){
671       dbString = fgkMCIdealStorage;
672     }
673     else if (strsimType == "Full"){
674       dbString = fgkMCFullStorage;
675     }
676     else if (strsimType == "Residual"){
677       dbString = fgkMCResidualStorage;
678     }
679     else {
680       AliFatal("Error in setting the storage for MC data, second argument MUST be either \"Ideal\" or \"Full\" or \"Residual\".");
681     }
682
683     SetDefaultStorage(dbString.Data());
684     fStartRunLHCPeriod=0;
685     fEndRunLHCPeriod=AliCDBRunRange::Infinity();
686     if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",dbString.Data()));
687   }
688 }
689
690 //_____________________________________________________________________________
691 void AliCDBManager::ValidateCvmfsCase() const {
692     if (! fCvmfsOcdb.BeginsWith("/cvmfs"))  //!!!! to be commented out for testing
693       AliFatal(Form("OCDB_PATH set to an invalid path: %s", fCvmfsOcdb.Data()));
694
695     TString cvmfsUri(fCvmfsOcdb);
696     gSystem->ExpandPathName(cvmfsUri);
697     if (gSystem->AccessPathName(cvmfsUri))
698       AliFatal(Form("OCDB_PATH set to an invalid path: %s", cvmfsUri.Data()));
699     
700     // check that we find the two scripts we need
701
702     AliDebug(3, "OCDB_PATH envvar is set. Changing OCDB storage from alien:// to local:///cvmfs type.");
703     cvmfsUri = cvmfsUri.Strip(TString::kTrailing, '/');
704     cvmfsUri.Append("/bin/getOCDBFilesPerRun.sh");
705     if (gSystem->AccessPathName(cvmfsUri))
706       AliFatal(Form("Cannot find valid script: %s", cvmfsUri.Data()));
707 }
708
709 //_____________________________________________________________________________
710 void AliCDBManager::SetDefaultStorageFromRun(Int_t run) {
711 // set default storage from the run number - to be used only with raw data      
712
713   // if lock is ON, cannot activate more storages!
714   if(fLock) {
715     if (fDefaultStorage) {
716       AliFatal("Lock is ON, and default storage is already set: "
717           "cannot activate default storage from run number");
718     }
719   }     
720
721   // fRaw and cvmfs case
722   if (! fCvmfsOcdb.IsNull()) {
723     // we don't want to connect to AliEn just to set the uri from the runnumber
724     // for that we use the script getUriFromYear.sh in the cvmfs AliRoot package
725     // check that we find the two scripts we need
726     TString getYearScript(fCvmfsOcdb);
727     getYearScript = getYearScript.Strip(TString::kTrailing, '/');
728     getYearScript.Append("/bin/getUriFromYear.sh");
729     if (gSystem->AccessPathName(getYearScript))
730       AliFatal(Form("Cannot find valid script: %s", getYearScript.Data()));
731     TString inoutFile(gSystem->WorkingDirectory());
732     inoutFile += "/uri_range_";
733     inoutFile += TString::Itoa(fRun,10);
734     TString command(getYearScript);
735     command += ' ';
736     command += TString::Itoa(fRun,10);
737     command += Form(" > %s", inoutFile.Data());
738     AliDebug(3, Form("Running command: \"%s\"",command.Data()));
739     Int_t result = gSystem->Exec(command.Data());
740     if(result != 0) {
741       AliFatal(Form("Was not able to execute \"%s\"", command.Data()));
742     }
743
744     // now read the file with the uri and first and last run
745     ifstream *file = new ifstream(inoutFile.Data());
746     if (!*file) {
747       AliFatal(Form("Error opening file \"%s\"!", inoutFile.Data()));
748     }
749     TString lhcPeriod;
750     TObjArray* oStringsArray = 0;
751     while (lhcPeriod.ReadLine(*file)){
752       oStringsArray = lhcPeriod.Tokenize(' ');
753     }
754     TObjString *oStrUri = dynamic_cast<TObjString*> (oStringsArray->At(0));
755     TObjString *oStrFirst = dynamic_cast<TObjString*> (oStringsArray->At(1));
756     TString firstRun = oStrFirst->GetString();
757     TObjString *oStrLast = dynamic_cast<TObjString*> (oStringsArray->At(2));
758     TString lastRun = oStrLast->GetString();
759
760     fLHCPeriod = oStrUri->GetString();
761     fStartRunLHCPeriod = firstRun.Atoi();
762     fEndRunLHCPeriod = lastRun.Atoi();
763
764     file->close();
765     delete file;
766
767   } else { // if not cvmfs case, "plain" AliEn case
768     // retrieve XML file from alien
769     if(!gGrid) {
770       TGrid::Connect("alien://","");
771       if(!gGrid) {
772         AliError("Connection to alien failed!");
773         return;
774       }
775     }
776     TUUID uuid;
777     TString rndname = "/tmp/";
778     rndname += "OCDBFolderXML.";
779     rndname += uuid.AsString();
780     rndname += ".xml";
781     AliDebug(2, Form("file to be copied = %s", fgkOCDBFolderXMLfile.Data()));
782     if (!TFile::Cp(fgkOCDBFolderXMLfile.Data(), rndname.Data())) {
783       AliFatal(Form("Cannot make a local copy of OCDBFolder xml file in %s",rndname.Data()));
784     }
785     AliCDBHandler* saxcdb = new AliCDBHandler();
786     saxcdb->SetRun(run);
787     TSAXParser *saxParser = new TSAXParser();
788     saxParser->ConnectToHandler("AliCDBHandler", saxcdb);
789     saxParser->ParseFile(rndname.Data());
790     AliInfo(Form(" LHC folder = %s", saxcdb->GetOCDBFolder().Data()));
791     AliInfo(Form(" LHC period start run = %d", saxcdb->GetStartRunRange()));
792     AliInfo(Form(" LHC period end run = %d", saxcdb->GetEndRunRange()));
793     fLHCPeriod = saxcdb->GetOCDBFolder();
794     fStartRunLHCPeriod = saxcdb->GetStartRunRange();
795     fEndRunLHCPeriod = saxcdb->GetEndRunRange();
796   }
797
798   SetDefaultStorage(fLHCPeriod.Data());
799   if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",fLHCPeriod.Data()));
800
801 }
802
803 //_____________________________________________________________________________
804 void AliCDBManager::UnsetDefaultStorage() {
805 // Unset default storage
806
807   // if lock is ON, action is forbidden!
808   if(fLock) {
809     if (fDefaultStorage) {
810       AliFatal("Lock is ON: cannot unset default storage!");
811     }
812   }
813
814   if (fDefaultStorage) {
815     AliWarning("Clearing cache!");
816     ClearCache();
817   }
818
819   fRun = fStartRunLHCPeriod = fEndRunLHCPeriod = -1;
820   fRaw = kFALSE;
821
822   fDefaultStorage = 0x0;
823 }
824
825 //_____________________________________________________________________________
826 void AliCDBManager::SetSpecificStorage(const char* calibType, const char* dbString) {
827 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
828
829   AliCDBParam *aPar = CreateParameter(dbString);
830   if(!aPar) return;
831   SetSpecificStorage(calibType, aPar);
832   delete aPar;
833 }
834
835 //_____________________________________________________________________________
836 void AliCDBManager::SetSpecificStorage(const char* calibType, const AliCDBParam* param) {
837 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
838 // Default storage should be defined prior to any specific storages, e.g.:
839 // AliCDBManager::instance()->SetDefaultStorage("alien://");
840 // AliCDBManager::instance()->SetSpecificStorage("TPC/*","local://DB_TPC");
841 // AliCDBManager::instance()->SetSpecificStorage("*/Align/*","local://DB_TPCAlign");
842 // calibType must be a valid CDB path! (3 level folder structure)
843
844
845   if(!fDefaultStorage && !fRaw) {
846     AliError("Please activate a default storage first!");
847     return;
848   }
849
850   AliCDBPath aPath(calibType);
851   if(!aPath.IsValid()){
852     AliError(Form("Not a valid path: %s", calibType));
853     return;
854   }
855
856   TObjString *objCalibType = new TObjString(aPath.GetPath());
857   if(fSpecificStorages.Contains(objCalibType)){
858     AliWarning(Form("Storage \"%s\" already activated! It will be replaced by the new one",
859           calibType));
860     AliCDBParam *checkPar = dynamic_cast<AliCDBParam*> (fSpecificStorages.GetValue(calibType));
861     if(checkPar) delete checkPar;
862     delete fSpecificStorages.Remove(objCalibType);
863   }
864   AliCDBStorage *aStorage = GetStorage(param);
865   if(!aStorage) return;
866
867   fSpecificStorages.Add(objCalibType, param->CloneParam());
868
869   if(fStorageMap->Contains(objCalibType)){
870     delete fStorageMap->Remove(objCalibType);
871   }
872   fStorageMap->Add(objCalibType->Clone(), new TObjString(param->GetURI()));
873
874 }
875
876 //_____________________________________________________________________________
877 AliCDBStorage* AliCDBManager::GetSpecificStorage(const char* calibType) {
878 // get storage specific for detector or calibration type
879
880   AliCDBPath calibPath(calibType);
881   if(!calibPath.IsValid()) return NULL;
882
883   AliCDBParam *checkPar = (AliCDBParam*) fSpecificStorages.GetValue(calibPath.GetPath());
884   if(!checkPar){
885     AliError(Form("%s storage not found!", calibType));
886     return NULL;
887   } else {
888     return GetStorage(checkPar);
889   }
890
891 }
892
893 //_____________________________________________________________________________
894 AliCDBParam* AliCDBManager::SelectSpecificStorage(const TString& path) {
895 // select storage valid for path from the list of specific storages
896
897   AliCDBPath aPath(path);
898   if(!aPath.IsValid()) return NULL;
899
900   TIter iter(&fSpecificStorages);
901   TObjString *aCalibType=0;
902   AliCDBPath tmpPath("null/null/null");
903   AliCDBParam* aPar=0;
904   while((aCalibType = (TObjString*) iter.Next())){
905     AliCDBPath calibTypePath(aCalibType->GetName());
906     if(calibTypePath.Comprises(aPath)) {
907       if(calibTypePath.Comprises(tmpPath)) continue;
908       aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
909       tmpPath.SetPath(calibTypePath.GetPath());
910     }
911   }
912   return aPar;
913 }
914
915 //_____________________________________________________________________________
916 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path, Int_t runNumber,
917     Int_t version, Int_t subVersion) {
918   // get an AliCDBEntry object from the database
919
920   if(runNumber < 0){
921     // RunNumber is not specified. Try with fRun
922     if (fRun < 0){
923       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
924       return NULL;
925     }
926     runNumber = fRun;
927   }
928
929   return Get(AliCDBId(path, runNumber, runNumber, version, subVersion));
930 }
931
932 //_____________________________________________________________________________
933 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path,
934     const AliCDBRunRange& runRange, Int_t version,
935     Int_t subVersion) {
936   // get an AliCDBEntry object from the database!
937
938   return Get(AliCDBId(path, runRange, version, subVersion));
939 }
940
941 //_____________________________________________________________________________
942 AliCDBEntry* AliCDBManager::Get(const AliCDBId& query, Bool_t forceCaching) {
943 // get an AliCDBEntry object from the database
944
945   // check if query's path and runRange are valid
946   // query is invalid also if version is not specified and subversion is!
947   if (!query.IsValid()) {
948     AliError(Form("Invalid query: %s", query.ToString().Data()));
949     return NULL;
950   }
951
952   // query is not specified if path contains wildcard or run range= [-1,-1]
953   if (!query.IsSpecified()) {
954     AliError(Form("Unspecified query: %s",
955           query.ToString().Data()));
956     return NULL;
957   }
958
959   if(fLock && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun()))
960     AliFatal("Lock is ON: cannot use different run number than the internal one!");
961
962   if(fCache && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun()))
963     AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
964
965   AliCDBEntry *entry=0;
966
967   // first look into map of cached objects
968   if(fCache && query.GetFirstRun() == fRun)
969     entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
970   if(entry) {
971     AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
972     return entry;
973   }
974
975   // if snapshot flag is set, try getting from the snapshot
976   // but in the case a specific storage is specified for this path
977   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
978   if(!aPar){
979     if(fSnapshotMode && query.GetFirstRun() == fRun)
980     {
981       entry = GetEntryFromSnapshot(query.GetPath());
982       if(entry) {
983         AliInfo(Form("Object \"%s\" retrieved from the snapshot.",query.GetPath().Data()));
984         if(query.GetFirstRun() == fRun) // no need to check fCache, fSnapshotMode not possible otherwise
985           CacheEntry(query.GetPath(), entry);
986
987         if(!fIds->Contains(&entry->GetId()))
988           fIds->Add(entry->GetId().Clone());
989
990         return entry;
991       }
992     }
993   }
994
995   // Entry is not in cache (and, in case we are in snapshot mode, not in the snapshot either)
996   // => retrieve it from the storage and cache it!!
997   if(!fDefaultStorage) {
998     AliError("No storage set!");
999     return NULL;
1000   }
1001
1002   AliCDBStorage *aStorage=0;
1003   if(aPar) {
1004     aStorage=GetStorage(aPar);
1005     TString str = aPar->GetURI();
1006     AliDebug(2,Form("Looking into storage: %s",str.Data()));
1007   } else {
1008     aStorage=GetDefaultStorage();
1009     AliDebug(2,"Looking into default storage");
1010   }
1011
1012   entry = aStorage->Get(query);
1013
1014   if(entry && fCache && (query.GetFirstRun()==fRun || forceCaching)){
1015     CacheEntry(query.GetPath(), entry);
1016   }
1017
1018   if(entry && !fIds->Contains(&entry->GetId())){
1019     fIds->Add(entry->GetId().Clone());
1020   }
1021
1022
1023   return entry;
1024
1025 }
1026
1027 //_____________________________________________________________________________
1028 AliCDBEntry* AliCDBManager::GetEntryFromSnapshot(const char* path) {
1029 // get the entry from the open snapshot file
1030
1031   TString sPath(path);
1032   sPath.ReplaceAll("/","*");
1033   if(!fSnapshotFile){
1034     AliError("No snapshot file is open!");
1035     return 0;
1036   }
1037   AliCDBEntry *entry = dynamic_cast<AliCDBEntry*>(fSnapshotFile->Get(sPath.Data()));
1038   if(!entry){
1039     AliDebug(2,Form("Cannot get a CDB entry for \"%s\" from snapshot file",path));
1040     return 0;
1041   }
1042
1043   return entry;
1044 }
1045
1046 //_____________________________________________________________________________
1047 Bool_t AliCDBManager::SetSnapshotMode(const char* snapshotFileName) {
1048 // set the manager in snapshot mode
1049
1050   if(!fCache){
1051     AliError("Cannot set the CDB manage in snapshot mode if the cache is not active!");
1052     return kFALSE;
1053   }
1054
1055   //open snapshot file
1056   TString snapshotFile(snapshotFileName);
1057   if(snapshotFile.BeginsWith("alien://")){
1058     if(!gGrid) {
1059       TGrid::Connect("alien://","");
1060       if(!gGrid) {
1061         AliError("Connection to alien failed!");
1062         return kFALSE;
1063       }
1064     }
1065   }
1066
1067   fSnapshotFile = TFile::Open(snapshotFileName);
1068   if (!fSnapshotFile || fSnapshotFile->IsZombie()){
1069     AliError(Form("Cannot open file %s",snapshotFileName));
1070     return kFALSE;
1071   }
1072
1073   AliInfo("The CDB manager is set in snapshot mode!");
1074   fSnapshotMode = kTRUE;
1075   return kTRUE;
1076
1077 }
1078
1079 //_____________________________________________________________________________
1080 const char* AliCDBManager::GetURI(const char* path) {
1081 // return the URI of the storage where to look for path
1082
1083   if(!IsDefaultStorageSet()) return 0;
1084
1085   AliCDBParam *aPar=SelectSpecificStorage(path);
1086
1087   if(aPar) {
1088     return aPar->GetURI().Data();
1089
1090   } else {
1091     return GetDefaultStorage()->GetURI().Data();
1092   }
1093
1094   return 0;
1095 }
1096
1097 //_____________________________________________________________________________
1098 Int_t AliCDBManager::GetStartRunLHCPeriod(){
1099 // get the first run of validity
1100 // for the current period
1101 // if set
1102   if(fStartRunLHCPeriod==-1)
1103     AliWarning("Run-range not yet set for the current LHC period.");
1104   return fStartRunLHCPeriod;
1105 }
1106
1107 //_____________________________________________________________________________
1108 Int_t AliCDBManager::GetEndRunLHCPeriod(){
1109 // get the last run of validity
1110 // for the current period
1111 // if set
1112   if(fEndRunLHCPeriod==-1)
1113     AliWarning("Run-range not yet set for the current LHC period.");
1114   return fEndRunLHCPeriod;
1115 }
1116
1117 //_____________________________________________________________________________
1118 TString AliCDBManager::GetLHCPeriod(){
1119 // get the current LHC period string
1120 //
1121   if(fLHCPeriod.IsWhitespace() || fLHCPeriod.IsNull())
1122     AliWarning("LHC period (OCDB folder) not yet set");
1123   return fLHCPeriod;
1124 }
1125
1126 //_____________________________________________________________________________
1127 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path, Int_t runNumber,
1128     Int_t version, Int_t subVersion) {
1129   // get the AliCDBId of the valid object from the database (does not retrieve the object)
1130   // User must delete returned object!
1131
1132   if(runNumber < 0){
1133     // RunNumber is not specified. Try with fRun
1134     if (fRun < 0){
1135       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
1136       return NULL;
1137     }
1138     runNumber = fRun;
1139   }
1140
1141   return GetId(AliCDBId(path, runNumber, runNumber, version, subVersion));
1142 }
1143
1144 //_____________________________________________________________________________
1145 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path,
1146     const AliCDBRunRange& runRange, Int_t version,
1147     Int_t subVersion) {
1148   // get the AliCDBId of the valid object from the database (does not retrieve the object)
1149   // User must delete returned object!
1150
1151   return GetId(AliCDBId(path, runRange, version, subVersion));
1152 }
1153
1154 //_____________________________________________________________________________
1155 AliCDBId* AliCDBManager::GetId(const AliCDBId& query) {
1156 // get the AliCDBId of the valid object from the database (does not retrieve the object)
1157 // User must delete returned object!
1158
1159   if(!fDefaultStorage) {
1160     AliError("No storage set!");
1161     return NULL;
1162   }
1163
1164   // check if query's path and runRange are valid
1165   // query is invalid also if version is not specified and subversion is!
1166   if (!query.IsValid()) {
1167     AliError(Form("Invalid query: %s", query.ToString().Data()));
1168     return NULL;
1169   }
1170
1171   // query is not specified if path contains wildcard or run range= [-1,-1]
1172   if (!query.IsSpecified()) {
1173     AliError(Form("Unspecified query: %s",
1174           query.ToString().Data()));
1175     return NULL;
1176   }
1177
1178   if(fCache && query.GetFirstRun() != fRun)
1179     AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
1180
1181   AliCDBEntry* entry = 0;
1182
1183   // first look into map of cached objects
1184   if(fCache && query.GetFirstRun() == fRun)
1185     entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
1186
1187   if(entry) {
1188     AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
1189     return dynamic_cast<AliCDBId*> (entry->GetId().Clone());
1190   }
1191
1192   // Entry is not in cache -> retrieve it from CDB and cache it!!
1193   AliCDBStorage *aStorage=0;
1194   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
1195
1196   if(aPar) {
1197     aStorage=GetStorage(aPar);
1198     TString str = aPar->GetURI();
1199     AliDebug(2,Form("Looking into storage: %s",str.Data()));
1200
1201   } else {
1202     aStorage=GetDefaultStorage();
1203     AliDebug(2,"Looking into default storage");
1204   }
1205
1206   return aStorage->GetId(query);
1207
1208 }
1209
1210 //_____________________________________________________________________________
1211 TList* AliCDBManager::GetAll(const AliCDBPath& path, Int_t runNumber,
1212     Int_t version, Int_t subVersion) {
1213   // get multiple AliCDBEntry objects from the database
1214
1215   if(runNumber < 0){
1216     // RunNumber is not specified. Try with fRun
1217     if (fRun < 0){
1218       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
1219       return NULL;
1220     }
1221     runNumber = fRun;
1222   }
1223
1224   return GetAll(AliCDBId(path, runNumber, runNumber, version,   
1225         subVersion));
1226 }
1227
1228 //_____________________________________________________________________________
1229 TList* AliCDBManager::GetAll(const AliCDBPath& path,
1230     const AliCDBRunRange& runRange, Int_t version, Int_t subVersion) {
1231   // get multiple AliCDBEntry objects from the database
1232
1233   return GetAll(AliCDBId(path, runRange, version, subVersion));
1234 }
1235
1236 //_____________________________________________________________________________
1237 TList* AliCDBManager::GetAll(const AliCDBId& query) {
1238 // get multiple AliCDBEntry objects from the database
1239 // Warning: this method works correctly only for queries of the type "Detector/*"
1240 //              and not for more specific queries e.g. "Detector/Calib/*" !
1241 // Warning #2: Entries are cached, but GetAll will keep on retrieving objects from OCDB!
1242 //              To get an object from cache use Get() function
1243
1244   if(!fDefaultStorage) {
1245     AliError("No storage set!");
1246     return NULL;
1247   }
1248
1249   if (!query.IsValid()) {
1250     AliError(Form("Invalid query: %s", query.ToString().Data()));
1251     return NULL;
1252   }
1253
1254   if((fSpecificStorages.GetEntries()>0) && query.GetPath().BeginsWith('*')){
1255     // if specific storages are active a query with "*" is ambiguous
1256     AliError("Query too generic in this context!");
1257     return NULL;
1258   }
1259
1260   if (query.IsAnyRange()) {
1261     AliError(Form("Unspecified run or runrange: %s",
1262           query.ToString().Data()));
1263     return NULL;
1264   }
1265
1266   if(fLock && query.GetFirstRun() != fRun)
1267     AliFatal("Lock is ON: cannot use different run number than the internal one!");
1268
1269   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
1270
1271   AliCDBStorage *aStorage;
1272   if(aPar) {
1273     aStorage=GetStorage(aPar);
1274     AliDebug(2,Form("Looking into storage: %s", aPar->GetURI().Data()));
1275
1276   } else {
1277     aStorage=GetDefaultStorage();
1278     AliDebug(2,Form("Looking into default storage: %s", aStorage->GetURI().Data()));
1279   }
1280
1281   TList *result = 0;
1282   if(aStorage) result = aStorage->GetAll(query);
1283   if(!result) return 0;
1284
1285   // loop on result to check whether entries should be re-queried with specific storages
1286   if(fSpecificStorages.GetEntries()>0 && ! (fSpecificStorages.GetEntries() == 1 && aPar)) {
1287     AliInfo("Now look into all other specific storages...");
1288
1289     TIter iter(result);
1290     AliCDBEntry* chkEntry=0;
1291
1292     while((chkEntry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
1293       AliCDBId& chkId = chkEntry->GetId();
1294       AliDebug(2, Form("Checking id %s ", chkId.GetPath().Data()));
1295       AliCDBParam *chkPar=SelectSpecificStorage(chkId.GetPath());
1296       if (!chkPar || aPar == chkPar) continue;
1297       AliCDBStorage *chkStorage = GetStorage(chkPar);
1298       AliDebug(2, Form("Found specific storage! %s", chkPar->GetURI().Data()));
1299
1300       AliCDBEntry *newEntry=0;
1301       chkId.SetRunRange(query.GetFirstRun(), query.GetLastRun());
1302       chkId.SetVersion(query.GetVersion());
1303       chkId.SetSubVersion(query.GetSubVersion());
1304
1305       if(chkStorage) newEntry = chkStorage->Get(chkId);
1306       if(!newEntry) continue;
1307
1308       // object is found in specific storage: replace entry in the result list!
1309       chkEntry->SetOwner(1);
1310       delete result->Remove(chkEntry);
1311       result->AddFirst(newEntry);
1312     }
1313
1314     Int_t nEntries = result->GetEntries();
1315     AliInfo("After look into other specific storages, result list is:");
1316     for(int i=0; i<nEntries;i++){
1317       AliCDBEntry *entry = (AliCDBEntry*) result->At(i);
1318       AliInfo(Form("%s",entry->GetId().ToString().Data()));
1319     }
1320   }
1321
1322   // caching entries
1323   TIter iter(result);
1324   AliCDBEntry* entry=0;
1325   while((entry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
1326
1327     if(!fIds->Contains(&entry->GetId())){
1328       fIds->Add(entry->GetId().Clone());
1329     }
1330     if(fCache && (query.GetFirstRun() == fRun)){
1331       CacheEntry(entry->GetId().GetPath(), entry);
1332     }
1333   }
1334
1335
1336   return result;
1337 }
1338
1339 //_____________________________________________________________________________
1340 Bool_t AliCDBManager::Put(TObject* object, const AliCDBId& id, AliCDBMetaData* metaData, const char* mirrors, DataType type){
1341 // store an AliCDBEntry object into the database
1342
1343   if (object==0x0) {
1344     AliError("Null Entry! No storage will be done!");
1345     return kFALSE;
1346   }
1347
1348   AliCDBEntry anEntry(object, id, metaData);
1349   return Put(&anEntry, mirrors, type);
1350
1351 }
1352
1353
1354 //_____________________________________________________________________________
1355 Bool_t AliCDBManager::Put(AliCDBEntry* entry, const char* mirrors, DataType type){
1356 // store an AliCDBEntry object into the database
1357
1358   if(type == kPrivate && !fDefaultStorage) {
1359     AliError("No storage set!");
1360     return kFALSE;
1361   }
1362
1363   if (!entry){
1364     AliError("No entry!");
1365     return kFALSE;
1366   }
1367
1368   if (entry->GetObject()==0x0){
1369     AliError("No valid object in CDB entry!");
1370     return kFALSE;
1371   }
1372
1373   if (!entry->GetId().IsValid()) {
1374     AliError(Form("Invalid entry ID: %s",
1375           entry->GetId().ToString().Data()));
1376     return kFALSE;
1377   }     
1378
1379   if (!entry->GetId().IsSpecified()) {
1380     AliError(Form("Unspecified entry ID: %s",
1381           entry->GetId().ToString().Data()));
1382     return kFALSE;
1383   }
1384
1385   AliCDBId id = entry->GetId();
1386   AliCDBParam *aPar = SelectSpecificStorage(id.GetPath());
1387
1388   AliCDBStorage *aStorage=0;
1389
1390   if(aPar) {
1391     aStorage=GetStorage(aPar);
1392   } else {
1393     switch(type){
1394       case kCondition:
1395         aStorage = GetStorage(fCondParam);
1396         break;
1397       case kReference:
1398         aStorage = GetStorage(fRefParam);
1399         break;
1400       case kPrivate:
1401         aStorage = GetDefaultStorage();
1402         break;
1403     }
1404   }
1405
1406   AliDebug(2,Form("Storing object into storage: %s", aStorage->GetURI().Data()));
1407
1408   TString strMirrors(mirrors);
1409   Bool_t result = kFALSE;
1410   if(!strMirrors.IsNull() && !strMirrors.IsWhitespace())
1411     result = aStorage->Put(entry, mirrors, type);
1412   else
1413     result = aStorage->Put(entry, "", type);
1414
1415   if(fRun >= 0) QueryCDB();
1416
1417   return result;
1418
1419
1420 }
1421
1422 //_____________________________________________________________________________
1423 void AliCDBManager::SetMirrorSEs(const char* mirrors) {
1424 // set mirror Storage Elements for the default storage, if it is of type "alien"
1425   if(fDefaultStorage->GetType() != "alien"){
1426     AliInfo("The default storage is not of type \"alien\". Settings for Storage Elements are not taken into account!");
1427     return;
1428   }
1429   fDefaultStorage->SetMirrorSEs(mirrors);
1430 }
1431
1432 //_____________________________________________________________________________
1433 const char* AliCDBManager::GetMirrorSEs() const {
1434 // get mirror Storage Elements for the default storage, if it is of type "alien"
1435   if(fDefaultStorage->GetType() != "alien"){
1436     AliInfo("The default storage is not of type \"alien\". Settings for Storage Elements are not taken into account!");
1437     return "";
1438   }
1439   return fDefaultStorage->GetMirrorSEs();
1440 }
1441
1442 //_____________________________________________________________________________
1443 void AliCDBManager::CacheEntry(const char* path, AliCDBEntry* entry) {
1444 // cache AliCDBEntry. Cache is valid until run number is changed.
1445
1446   AliCDBEntry *chkEntry = dynamic_cast<AliCDBEntry*> (fEntryCache.GetValue(path));
1447
1448   if(chkEntry) {
1449     AliDebug(2, Form("Object %s already in cache !!", path));
1450     return;
1451   } else {
1452     AliDebug(2,Form("Caching entry %s", path));
1453   }
1454
1455   fEntryCache.Add(new TObjString(path), entry);
1456   AliDebug(2,Form("Cache entries: %d", fEntryCache.GetEntries()));
1457
1458 }
1459
1460 //_____________________________________________________________________________
1461 void AliCDBManager::Print(Option_t* /*option*/) const {
1462 // Print list of active storages and their URIs
1463
1464   TString output=Form("Run number = %d; ",fRun);
1465   output += "Cache is ";
1466   if(!fCache) output += "NOT ";
1467   output += Form("ACTIVE; Number of active storages: %d\n",fActiveStorages.GetEntries());
1468
1469   if(fDefaultStorage) {
1470     output += Form("\t*** Default Storage URI: \"%s\"\n",fDefaultStorage->GetURI().Data());
1471     //          AliInfo(output.Data());
1472   }
1473   if(fSpecificStorages.GetEntries()>0) {
1474     TIter iter(fSpecificStorages.GetTable());
1475     TPair *aPair=0;
1476     Int_t i=1;
1477     while((aPair = (TPair*) iter.Next())){
1478       output += Form("\t*** Specific storage %d: Path \"%s\" -> URI \"%s\"\n",
1479           i++, ((TObjString*) aPair->Key())->GetName(),
1480           ((AliCDBParam*) aPair->Value())->GetURI().Data());
1481     }
1482   }
1483   if(fDrainStorage) {
1484     output += Form("*** Drain Storage URI: %s\n",fDrainStorage->GetURI().Data());
1485   }
1486   AliInfo(output.Data());
1487 }
1488
1489 //_____________________________________________________________________________
1490 void AliCDBManager::SetRun(Int_t run) {
1491 // Sets current run number.
1492 // When the run number changes the caching is cleared.
1493
1494   if(fRun == run)
1495     return;
1496
1497   if(fLock && fRun >= 0) {
1498     AliFatal("Lock is ON, cannot reset run number!");
1499   }     
1500
1501   fRun = run;
1502
1503   if (fRaw) {
1504     // here the LHCPeriod xml file is parsed; the string containing the correct period is returned; the default storage is set
1505     if (fStartRunLHCPeriod <= run && fEndRunLHCPeriod >= run){
1506       AliInfo("LHCPeriod alien folder for current run already in memory");
1507     }else{
1508       SetDefaultStorageFromRun(run);
1509       if(fEntryCache.GetEntries()!=0) ClearCache();
1510       return;
1511     }
1512   }
1513   ClearCache();
1514   QueryCDB();
1515 }
1516
1517 //_____________________________________________________________________________
1518 void AliCDBManager::ClearCache(){
1519 // clear AliCDBEntry cache
1520
1521   AliDebug(2, Form("Cache entries to be deleted: %d",fEntryCache.GetEntries()));
1522
1523   /*
1524   // To clean entries one by one
1525   TIter iter(fEntryCache.GetTable());
1526   TPair* pair=0;
1527   while((pair= dynamic_cast<TPair*> (iter.Next()))){
1528
1529   TObjString* key = dynamic_cast<TObjString*> (pair->Key());
1530   AliCDBEntry* entry = dynamic_cast<AliCDBEntry*> (pair->Value());
1531   AliDebug(2, Form("Deleting entry: %s", key->GetName()));
1532   if (entry) delete entry;
1533   delete fEntryCache.Remove(key);
1534   }
1535   */
1536   fEntryCache.DeleteAll();
1537   AliDebug(2, Form("After deleting - Cache entries: %d",fEntryCache.GetEntries()));
1538 }
1539
1540 //_____________________________________________________________________________
1541 void AliCDBManager::UnloadFromCache(const char* path){
1542 // unload cached object
1543 // that is remove the entry from the cache and the id from the list of ids
1544 //
1545   if(!fActiveStorages.GetEntries()) {
1546     AliDebug(2, Form("No active storages. Object \"%s\" is not unloaded from cache", path));
1547     return;
1548   }
1549
1550   AliCDBPath queryPath(path);
1551   if(!queryPath.IsValid()) return;
1552
1553   if(!queryPath.IsWildcard()) { // path is not wildcard, get it directly from the cache and unload it!
1554     if(fEntryCache.Contains(path)){
1555       AliDebug(2, Form("Unloading object \"%s\" from cache and from list of ids", path));
1556       TObjString pathStr(path);
1557       delete fEntryCache.Remove(&pathStr);
1558       // we do not remove from the list of Id's (it's not very coherent but we leave the
1559       // id for the benefit of the userinfo)
1560       /*
1561          TIter iter(fIds);
1562          AliCDBId *id = 0;
1563          while((id = dynamic_cast<AliCDBId*> (iter.Next()))){
1564          if(queryPath.Comprises(id->GetPath()))
1565          delete fIds->Remove(id);
1566          }*/
1567     } else {
1568       AliWarning(Form("Cache does not contain object \"%s\"!", path));
1569     }
1570     AliDebug(2, Form("Cache entries: %d",fEntryCache.GetEntries()));
1571     return;
1572   }
1573
1574   // path is wildcard: loop on the cache and unload all comprised objects!
1575   TIter iter(fEntryCache.GetTable());
1576   TPair* pair = 0;
1577   Int_t removed=0;
1578
1579   while((pair = dynamic_cast<TPair*> (iter.Next()))){
1580     AliCDBPath entryPath = pair->Key()->GetName();
1581     if(queryPath.Comprises(entryPath)) {
1582       AliDebug(2, Form("Unloading object \"%s\" from cache and from list of ids", entryPath.GetPath().Data()));
1583       TObjString pathStr(entryPath.GetPath());
1584       delete fEntryCache.Remove(&pathStr);
1585       removed++;
1586
1587       // we do not remove from the list of Id's (it's not very coherent but we leave the
1588       // id for the benefit of the userinfo)
1589       /*
1590          TIter iterids(fIds);
1591          AliCDBId *anId = 0;
1592          while((anId = dynamic_cast<AliCDBId*> (iterids.Next()))){
1593          AliCDBPath aPath = anId->GetPath();
1594          TString aPathStr = aPath.GetPath();
1595          if(queryPath.Comprises(aPath)) {
1596          delete fIds->Remove(anId);
1597          }
1598          }*/
1599     }
1600   }
1601   AliDebug(2,Form("Cache entries and ids removed: %d   Remaining: %d",removed,fEntryCache.GetEntries()));
1602 }
1603
1604 //_____________________________________________________________________________
1605 void AliCDBManager::DestroyActiveStorages() {
1606 // delete list of active storages
1607
1608   fActiveStorages.DeleteAll();
1609   fSpecificStorages.DeleteAll();
1610 }
1611
1612 //_____________________________________________________________________________
1613 void AliCDBManager::DestroyActiveStorage(AliCDBStorage* /*storage*/) {
1614 // destroys active storage
1615
1616   /*
1617      TIter iter(fActiveStorages.GetTable());
1618      TPair* aPair;
1619      while ((aPair = (TPair*) iter.Next())) {
1620      if(storage == (AliCDBStorage*) aPair->Value())
1621      delete fActiveStorages.Remove(aPair->Key());
1622      storage->Delete(); storage=0x0;
1623      }
1624      */
1625
1626 }
1627
1628 //_____________________________________________________________________________
1629 void AliCDBManager::QueryCDB() {
1630 // query default and specific storages for files valid for fRun. Every storage loads the Ids into its list.
1631
1632   if (fRun < 0){
1633     AliError("Run number not yet set! Use AliCDBManager::SetRun.");
1634     return;
1635   }
1636   if (!fDefaultStorage){
1637     AliError("Default storage is not set! Use AliCDBManager::SetDefaultStorage");
1638     return;
1639   }
1640   if(fDefaultStorage->GetType() == "alien" || fDefaultStorage->GetType() == "local"){
1641     fDefaultStorage->QueryCDB(fRun);
1642   //} else {
1643   //    AliDebug(2,"Skipping query for valid files, it used only in grid...");
1644   }
1645
1646   TIter iter(&fSpecificStorages);
1647   TObjString *aCalibType=0;
1648   AliCDBParam* aPar=0;
1649   while((aCalibType = dynamic_cast<TObjString*> (iter.Next()))){
1650     aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
1651     if(aPar) {
1652       AliDebug(2,Form("Querying specific storage %s",aCalibType->GetName()));
1653       AliCDBStorage *aStorage = GetStorage(aPar);
1654       if(aStorage->GetType() == "alien" || aStorage->GetType() == "local"){
1655         aStorage->QueryCDB(fRun, aCalibType->GetName());
1656       } else {
1657         AliDebug(2,
1658             "Skipping query for valid files, it is used only in grid...");
1659       }
1660     }
1661   }
1662 }
1663
1664 //______________________________________________________________________________________________
1665 const char* AliCDBManager::GetDataTypeName(DataType type) {
1666 // returns the name (string) of the data type
1667
1668   switch (type){
1669     case kCondition: return "Conditions";
1670     case kReference: return "Reference";
1671     case kPrivate: return "Private";
1672   }
1673   return 0;
1674
1675 }
1676
1677 //______________________________________________________________________________________________
1678 Bool_t AliCDBManager::DiffObjects(const char *cdbFile1, const char *cdbFile2) const {
1679 // Compare byte-by-byte the objects contained in the CDB entry in two different files,
1680 // whose name is passed as input
1681 // Return value:
1682 //   kTRUE - in case the content of the OCDB object (persistent part) is exactly the same
1683 //   kFALSE - otherwise
1684
1685   TString f1Str(cdbFile1);
1686   TString f2Str(cdbFile2);
1687   if (!gGrid && ( f1Str.BeginsWith("alien://") || f2Str.BeginsWith("alien://") ))
1688     TGrid::Connect("alien://");
1689
1690   TFile * f1 = TFile::Open(cdbFile1);
1691   if (!f1){
1692     Printf("Cannot open file \"%s\"",cdbFile1);
1693     return kFALSE;
1694   }
1695   TFile * f2 = TFile::Open(cdbFile2);
1696   if (!f2){
1697     Printf("Cannot open file \"%s\"",cdbFile2);
1698     return kFALSE;
1699   }
1700
1701   AliCDBEntry * entry1 = (AliCDBEntry*)f1->Get("AliCDBEntry");
1702   if (!entry1){
1703     Printf("Cannot get CDB entry from file \"%s\"",cdbFile1);
1704     return kFALSE;
1705   }
1706   AliCDBEntry * entry2 = (AliCDBEntry*)f2->Get("AliCDBEntry");
1707   if (!entry2){
1708     Printf("Cannot get CDB entry from file \"%s\"",cdbFile2);
1709     return kFALSE;
1710   }
1711
1712   // stream the two objects in the buffer of two TMessages
1713   TObject* object1 = entry1->GetObject();
1714   TObject* object2 = entry2->GetObject();
1715   TMessage * file1 = new TMessage(TBuffer::kWrite);
1716   file1->WriteObject(object1);
1717   Int_t size1 = file1->Length();
1718   TMessage * file2 = new TMessage(TBuffer::kWrite);
1719   file2->WriteObject(object2);
1720   Int_t size2 = file2->Length();
1721   if (size1!=size2){
1722     Printf("Problem 2:  OCDB entry of different size (%d,%d)",size1,size2);
1723     return kFALSE;
1724   }
1725
1726   // if the two buffers have the same size, check that they are the same byte-by-byte
1727   Int_t countDiff=0;
1728   char* buf1 = file1->Buffer();
1729   char* buf2 = file2->Buffer();
1730   //for (Int_t i=0; i<size1; i++)    if (file1->Buffer()[i]!=file2->Buffer()[i]) countDiff++;
1731   for(Int_t i=0; i<size1; i++)
1732     if (buf1[i]!=buf2[i]) countDiff++;
1733
1734   if (countDiff>0){
1735     Printf("The CDB objects differ by %d bytes.", countDiff);
1736     return kFALSE;
1737   }
1738
1739   Printf("The CDB objects are the same in the two files.");
1740   return kTRUE;
1741 }
1742
1743 //______________________________________________________________________________________________
1744 void AliCDBManager::InitShortLived() {
1745 // Init the list of short-lived objects
1746 // currently disabled
1747
1748   fShortLived=0x0;
1749
1750   //    fShortLived = new TList();
1751   //    fShortLived->SetOwner(1);
1752   //
1753   //    fShortLived->Add(new TObjString("EMCAL/Calib/Data"));
1754   //
1755   //    fShortLived->Add(new TObjString("HMPID/Calib/Nmean"));
1756   //    fShortLived->Add(new TObjString("HMPID/Calib/Qthre"));
1757   //
1758   //    fShortLived->Add(new TObjString("ITS/Calib/CalibSPD"));
1759   //
1760   //    fShortLived->Add(new TObjString("MUON/Calib/Gains"));
1761   //    fShortLived->Add(new TObjString("MUON/Calib/HV"));
1762   //    fShortLived->Add(new TObjString("MUON/Calib/Pedestals"));
1763   //
1764   //    fShortLived->Add(new TObjString("PHOS/Calib/CpvGainPedestals"));
1765   //    fShortLived->Add(new TObjString("PHOS/Calib/EmcGainPedestals"));
1766   //
1767   //    fShortLived->Add(new TObjString("PMD/Calib/Data"));
1768   //
1769   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberGainFactor"));
1770   //    fShortLived->Add(new TObjString("TRD/Calib/LocalGainFactor"));
1771   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberT0"));
1772   //    fShortLived->Add(new TObjString("TRD/Calib/LocalT0"));
1773   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberVdrift"));
1774   //    fShortLived->Add(new TObjString("TRD/Calib/LocalVdrift"));
1775   //
1776   //    fShortLived->Add(new TObjString("ZDC/Calib/Data"));
1777
1778 }
1779
1780 //______________________________________________________________________________________________
1781 Bool_t AliCDBManager::IsShortLived(const char* path) {
1782 // returns the name (string) of the data type
1783
1784   if(!fShortLived) return kFALSE;
1785
1786   AliCDBPath aPath(path);
1787   if(!aPath.IsValid()){
1788     AliError(Form("Not a valid path: %s", path));
1789     return kFALSE;
1790   }
1791
1792   return fShortLived->Contains(path);
1793
1794 }
1795
1796 //______________________________________________________________________________________________
1797 ULong64_t AliCDBManager::SetLock(Bool_t lock, ULong64_t key){
1798 // To lock/unlock user must provide the key. A new key is provided after
1799 // each successful lock. User should always backup the returned key and
1800 // use it on next access.
1801   if (fLock == lock) return 0;  // nothing to be done
1802   if (lock) {
1803     // User wants to lock - check his identity
1804     if (fKey) {
1805       // Lock has a user - check his key
1806       if (fKey != key) {
1807         AliFatal("Wrong key provided to lock CDB. Please remove CDB lock access from your code !");
1808         return 0;
1809       }
1810     }
1811     // Provide new key
1812     fKey = gSystem->Now();
1813     fLock = kTRUE;
1814     return fKey;
1815   }
1816   // User wants to unlock - check the provided key
1817   if (key != fKey) {
1818     AliFatal("Lock is ON: wrong key provided");
1819     return 0;
1820   }
1821   fLock = kFALSE;
1822   return key;
1823 }
1824
1825 ///////////////////////////////////////////////////////////
1826 // AliCDBManager Parameter class                         //
1827 // interface to specific AliCDBParameter class           //
1828 // (AliCDBGridParam, AliCDBLocalParam, AliCDBDumpParam)  //
1829 ///////////////////////////////////////////////////////////
1830
1831 AliCDBParam::AliCDBParam():
1832   fType(),
1833   fURI()
1834 {
1835   // constructor
1836
1837 }
1838
1839 //_____________________________________________________________________________
1840 AliCDBParam::~AliCDBParam() {
1841   // destructor
1842
1843 }
1844