]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/CDB/AliCDBManager.cxx
1573fee288d8558f00c3398c92b2678b1f012ae8
[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         //} else {
506         //      AliDebug(2,
507         //              "Skipping query for valid files, it is used only in grid...");
508         //}
509     }
510     return aStorage;
511   }
512 }
513
514 AliError(Form("Failed to activate requested storage! Check URI: %s", param->GetURI().Data()));
515
516 return NULL;
517 }
518
519 //_____________________________________________________________________________
520 AliCDBStorage* AliCDBManager::GetActiveStorage(const AliCDBParam* param) {
521 // get a storage object from the list of active storages
522
523   return dynamic_cast<AliCDBStorage*> (fActiveStorages.GetValue(param));
524 }
525
526 //_____________________________________________________________________________
527 TList* AliCDBManager::GetActiveStorages() {
528 // return list of active storages
529 // user has responsibility to delete returned object
530
531   TList* result = new TList();
532
533   TIter iter(fActiveStorages.GetTable());
534   TPair* aPair=0;
535   while ((aPair = (TPair*) iter.Next())) {
536     result->Add(aPair->Value());
537   }
538
539   return result;
540 }
541
542 //_____________________________________________________________________________
543 void AliCDBManager::SetDrain(const char* dbString) {
544 // set drain storage from URI string
545
546   fDrainStorage = GetStorage(dbString); 
547 }
548
549 //_____________________________________________________________________________
550 void AliCDBManager::SetDrain(const AliCDBParam* param) {
551 // set drain storage from AliCDBParam
552
553   fDrainStorage = GetStorage(param);
554 }
555
556 //_____________________________________________________________________________
557 void AliCDBManager::SetDrain(AliCDBStorage* storage) {
558 // set drain storage from another active storage
559
560   fDrainStorage = storage;
561 }
562
563 //_____________________________________________________________________________
564 Bool_t AliCDBManager::Drain(AliCDBEntry *entry) {
565 // drain retrieved object to drain storage
566
567   AliDebug(2, "Draining into drain storage...");
568   return fDrainStorage->Put(entry);
569 }
570
571 //____________________________________________________________________________
572 void AliCDBManager::SetDefaultStorage(const char* storageUri) {
573 // sets default storage from URI string
574
575   // if in the cvmfs case (triggered by environment variable) check for path validity
576   // and modify Uri if it is "raw://"
577   TString cvmfsOcdb(gSystem->Getenv("OCDB_PATH"));
578   if (! cvmfsOcdb.IsNull()){
579     fCvmfsOcdb = cvmfsOcdb;
580     ValidateCvmfsCase();
581   }
582
583   // checking whether we are in the raw case
584   TString uriTemp(storageUri);
585   if (uriTemp == "raw://") {
586     fRaw = kTRUE; // read then by SetRun to check if the method has to be called again with expanded uri
587     AliInfo("Setting the run-number will set the corresponding OCDB for raw data reconstruction.");
588     return;
589   }
590
591   AliCDBStorage* bckStorage = fDefaultStorage;
592
593   fDefaultStorage = GetStorage(storageUri);
594
595   if(!fDefaultStorage) return;
596
597   if(bckStorage && (fDefaultStorage != bckStorage)){
598     AliWarning("Existing default storage replaced: clearing cache!");
599     ClearCache();
600   }
601
602   if (fStorageMap->Contains("default")) {
603     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
604   }
605   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
606 }
607
608 //_____________________________________________________________________________
609 void AliCDBManager::SetDefaultStorage(const AliCDBParam* param) {
610 // set default storage from AliCDBParam object
611
612   AliCDBStorage* bckStorage = fDefaultStorage;
613
614   fDefaultStorage = GetStorage(param);
615
616   if(!fDefaultStorage) return;
617
618   if(bckStorage && (fDefaultStorage != bckStorage)){
619     AliWarning("Existing default storage replaced: clearing cache!");
620     ClearCache();
621   }
622
623   if (fStorageMap->Contains("default")) {
624     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
625   }
626   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
627 }
628
629 //_____________________________________________________________________________
630 void AliCDBManager::SetDefaultStorage(AliCDBStorage* storage) {
631 // set default storage from another active storage
632
633   // if lock is ON, cannot activate more storages!
634   if(fLock) {
635     if (fDefaultStorage) {
636       AliFatal("Lock is ON, and default storage is already set: "
637           "cannot reset it or activate more storages!");
638     }
639   }     
640
641   if (!storage) {
642     UnsetDefaultStorage();
643     return;
644   }
645
646   AliCDBStorage* bckStorage = fDefaultStorage;
647
648   fDefaultStorage = storage;
649
650   if(bckStorage && (fDefaultStorage != bckStorage)){
651     AliWarning("Existing default storage replaced: clearing cache!");
652     ClearCache();
653   }
654
655   if (fStorageMap->Contains("default")) {
656     delete fStorageMap->Remove(((TPair*)fStorageMap->FindObject("default"))->Key());
657   }
658   fStorageMap->Add(new TObjString("default"), new TObjString(fDefaultStorage->GetURI()));
659 }
660
661 //_____________________________________________________________________________
662 void AliCDBManager::SetDefaultStorage(const char* mcString, const char* simType) {
663 // sets default storage for MC data
664 // mcString MUST be "MC",
665 // simType can be "Ideal","Residual","Full"
666
667   TString strmcString(mcString);
668   TString strsimType(simType);
669   TString dbString;
670   if (strmcString != "MC"){
671     AliFatal("Method requires first string to be MC!");
672   }
673   else {
674     if (strsimType == "Ideal"){
675       dbString = fgkMCIdealStorage;
676     }
677     else if (strsimType == "Full"){
678       dbString = fgkMCFullStorage;
679     }
680     else if (strsimType == "Residual"){
681       dbString = fgkMCResidualStorage;
682     }
683     else {
684       AliFatal("Error in setting the storage for MC data, second argument MUST be either \"Ideal\" or \"Full\" or \"Residual\".");
685     }
686
687     SetDefaultStorage(dbString.Data());
688     fStartRunLHCPeriod=0;
689     fEndRunLHCPeriod=AliCDBRunRange::Infinity();
690     if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",dbString.Data()));
691   }
692 }
693
694 //_____________________________________________________________________________
695 void AliCDBManager::ValidateCvmfsCase() const {
696     if (! fCvmfsOcdb.BeginsWith("/cvmfs"))  //!!!! to be commented out for testing
697       AliFatal(Form("OCDB_PATH set to an invalid path: %s", fCvmfsOcdb.Data()));
698
699     TString cvmfsUri(fCvmfsOcdb);
700     gSystem->ExpandPathName(cvmfsUri);
701     if (gSystem->AccessPathName(cvmfsUri))
702       AliFatal(Form("OCDB_PATH set to an invalid path: %s", cvmfsUri.Data()));
703     
704     // check that we find the two scripts we need
705
706     AliDebug(3, "OCDB_PATH envvar is set. Changing OCDB storage from alien:// to local:///cvmfs type.");
707     cvmfsUri = cvmfsUri.Strip(TString::kTrailing, '/');
708     cvmfsUri.Append("/bin/getOCDBFilesPerRun.sh");
709     if (gSystem->AccessPathName(cvmfsUri))
710       AliFatal(Form("Cannot find valid script: %s", cvmfsUri.Data()));
711 }
712
713 //_____________________________________________________________________________
714 void AliCDBManager::SetDefaultStorageFromRun(Int_t run) {
715 // set default storage from the run number - to be used only with raw data      
716
717   // if lock is ON, cannot activate more storages!
718   if(fLock) {
719     if (fDefaultStorage) {
720       AliFatal("Lock is ON, and default storage is already set: "
721           "cannot activate default storage from run number");
722     }
723   }     
724
725   // fRaw and cvmfs case
726   if (! fCvmfsOcdb.IsNull()) {
727     // we don't want to connect to AliEn just to set the uri from the runnumber
728     // for that we use the script getUriFromYear.sh in the cvmfs AliRoot package
729     // check that we find the two scripts we need
730     TString getYearScript(fCvmfsOcdb);
731     getYearScript = getYearScript.Strip(TString::kTrailing, '/');
732     getYearScript.Append("/bin/getUriFromYear.sh");
733     if (gSystem->AccessPathName(getYearScript))
734       AliFatal(Form("Cannot find valid script: %s", getYearScript.Data()));
735     TString inoutFile(gSystem->WorkingDirectory());
736     inoutFile += "/uri_range_";
737     inoutFile += TString::Itoa(fRun,10);
738     TString command(getYearScript);
739     command += ' ';
740     command += TString::Itoa(fRun,10);
741     command += Form(" > %s", inoutFile.Data());
742     AliDebug(3, Form("Running command: \"%s\"",command.Data()));
743     Int_t result = gSystem->Exec(command.Data());
744     if(result != 0) {
745       AliFatal(Form("Was not able to execute \"%s\"", command.Data()));
746     }
747
748     // now read the file with the uri and first and last run
749     ifstream *file = new ifstream(inoutFile.Data());
750     if (!*file) {
751       AliFatal(Form("Error opening file \"%s\"!", inoutFile.Data()));
752       file->close();
753       delete file;
754     }
755     TString lhcPeriod;
756     TObjArray* oStringsArray = 0;
757     while (lhcPeriod.ReadLine(*file)){
758       oStringsArray = lhcPeriod.Tokenize(' ');
759     }
760     TObjString *oStrUri = dynamic_cast<TObjString*> (oStringsArray->At(0));
761     TObjString *oStrFirst = dynamic_cast<TObjString*> (oStringsArray->At(1));
762     TString firstRun = oStrFirst->GetString();
763     TObjString *oStrLast = dynamic_cast<TObjString*> (oStringsArray->At(2));
764     TString lastRun = oStrLast->GetString();
765
766     fLHCPeriod = oStrUri->GetString();
767     fStartRunLHCPeriod = firstRun.Atoi();
768     fEndRunLHCPeriod = lastRun.Atoi();
769
770     file->close();
771     delete file;
772
773   } else { // if not cvmfs case, "plain" AliEn case
774     // retrieve XML file from alien
775     if(!gGrid) {
776       TGrid::Connect("alien://","");
777       if(!gGrid) {
778         AliError("Connection to alien failed!");
779         return;
780       }
781     }
782     TUUID uuid;
783     TString rndname = "/tmp/";
784     rndname += "OCDBFolderXML.";
785     rndname += uuid.AsString();
786     rndname += ".xml";
787     AliDebug(2, Form("file to be copied = %s", fgkOCDBFolderXMLfile.Data()));
788     if (!TFile::Cp(fgkOCDBFolderXMLfile.Data(), rndname.Data())) {
789       AliFatal(Form("Cannot make a local copy of OCDBFolder xml file in %s",rndname.Data()));
790     }
791     AliCDBHandler* saxcdb = new AliCDBHandler();
792     saxcdb->SetRun(run);
793     TSAXParser *saxParser = new TSAXParser();
794     saxParser->ConnectToHandler("AliCDBHandler", saxcdb);
795     saxParser->ParseFile(rndname.Data());
796     AliInfo(Form(" LHC folder = %s", saxcdb->GetOCDBFolder().Data()));
797     AliInfo(Form(" LHC period start run = %d", saxcdb->GetStartRunRange()));
798     AliInfo(Form(" LHC period end run = %d", saxcdb->GetEndRunRange()));
799     fLHCPeriod = saxcdb->GetOCDBFolder();
800     fStartRunLHCPeriod = saxcdb->GetStartRunRange();
801     fEndRunLHCPeriod = saxcdb->GetEndRunRange();
802   }
803
804   SetDefaultStorage(fLHCPeriod.Data());
805   if(!fDefaultStorage) AliFatal(Form("%s storage not there! Please check!",fLHCPeriod.Data()));
806
807 }
808
809 //_____________________________________________________________________________
810 void AliCDBManager::UnsetDefaultStorage() {
811 // Unset default storage
812
813   // if lock is ON, action is forbidden!
814   if(fLock) {
815     if (fDefaultStorage) {
816       AliFatal("Lock is ON: cannot unset default storage!");
817     }
818   }
819
820   if (fDefaultStorage) {
821     AliWarning("Clearing cache!");
822     ClearCache();
823   }
824
825   fRun = fStartRunLHCPeriod = fEndRunLHCPeriod = -1;
826   fRaw = kFALSE;
827
828   fDefaultStorage = 0x0;
829 }
830
831 //_____________________________________________________________________________
832 void AliCDBManager::SetSpecificStorage(const char* calibType, const char* dbString) {
833 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
834
835   AliCDBParam *aPar = CreateParameter(dbString);
836   if(!aPar) return;
837   SetSpecificStorage(calibType, aPar);
838   delete aPar;
839 }
840
841 //_____________________________________________________________________________
842 void AliCDBManager::SetSpecificStorage(const char* calibType, const AliCDBParam* param) {
843 // sets storage specific for detector or calibration type (works with AliCDBManager::Get(...))
844 // Default storage should be defined prior to any specific storages, e.g.:
845 // AliCDBManager::instance()->SetDefaultStorage("alien://");
846 // AliCDBManager::instance()->SetSpecificStorage("TPC/*","local://DB_TPC");
847 // AliCDBManager::instance()->SetSpecificStorage("*/Align/*","local://DB_TPCAlign");
848 // calibType must be a valid CDB path! (3 level folder structure)
849
850
851   if(!fDefaultStorage && !fRaw) {
852     AliError("Please activate a default storage first!");
853     return;
854   }
855
856
857   AliCDBPath aPath(calibType);
858   if(!aPath.IsValid()){
859     AliError(Form("Not a valid path: %s", calibType));
860     return;
861   }
862
863   TObjString *objCalibType = new TObjString(aPath.GetPath());
864   if(fSpecificStorages.Contains(objCalibType)){
865     AliWarning(Form("Storage \"%s\" already activated! It will be replaced by the new one",
866           calibType));
867     AliCDBParam *checkPar = dynamic_cast<AliCDBParam*> (fSpecificStorages.GetValue(calibType));
868     if(checkPar) delete checkPar;
869     delete fSpecificStorages.Remove(objCalibType);
870   }
871   AliCDBStorage *aStorage = GetStorage(param);
872   if(!aStorage) return;
873
874   fSpecificStorages.Add(objCalibType, param->CloneParam());
875
876   if(fStorageMap->Contains(objCalibType)){
877     delete fStorageMap->Remove(objCalibType);
878   }
879   fStorageMap->Add(objCalibType->Clone(), new TObjString(param->GetURI()));
880
881 }
882
883 //_____________________________________________________________________________
884 AliCDBStorage* AliCDBManager::GetSpecificStorage(const char* calibType) {
885 // get storage specific for detector or calibration type
886
887   AliCDBPath calibPath(calibType);
888   if(!calibPath.IsValid()) return NULL;
889
890   AliCDBParam *checkPar = (AliCDBParam*) fSpecificStorages.GetValue(calibPath.GetPath());
891   if(!checkPar){
892     AliError(Form("%s storage not found!", calibType));
893     return NULL;
894   } else {
895     return GetStorage(checkPar);
896   }
897
898 }
899
900 //_____________________________________________________________________________
901 AliCDBParam* AliCDBManager::SelectSpecificStorage(const TString& path) {
902 // select storage valid for path from the list of specific storages
903
904   AliCDBPath aPath(path);
905   if(!aPath.IsValid()) return NULL;
906
907   TIter iter(&fSpecificStorages);
908   TObjString *aCalibType=0;
909   AliCDBPath tmpPath("null/null/null");
910   AliCDBParam* aPar=0;
911   while((aCalibType = (TObjString*) iter.Next())){
912     AliCDBPath calibTypePath(aCalibType->GetName());
913     if(calibTypePath.Comprises(aPath)) {
914       if(calibTypePath.Comprises(tmpPath)) continue;
915       aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
916       tmpPath.SetPath(calibTypePath.GetPath());
917     }
918   }
919   return aPar;
920 }
921
922 //_____________________________________________________________________________
923 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path, Int_t runNumber,
924     Int_t version, Int_t subVersion) {
925   // get an AliCDBEntry object from the database
926
927   if(runNumber < 0){
928     // RunNumber is not specified. Try with fRun
929     if (fRun < 0){
930       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
931       return NULL;
932     }
933     runNumber = fRun;
934   }
935
936   return Get(AliCDBId(path, runNumber, runNumber, version, subVersion));
937 }
938
939 //_____________________________________________________________________________
940 AliCDBEntry* AliCDBManager::Get(const AliCDBPath& path,
941     const AliCDBRunRange& runRange, Int_t version,
942     Int_t subVersion) {
943   // get an AliCDBEntry object from the database!
944
945   return Get(AliCDBId(path, runRange, version, subVersion));
946 }
947
948 //_____________________________________________________________________________
949 AliCDBEntry* AliCDBManager::Get(const AliCDBId& query, Bool_t forceCaching) {
950 // get an AliCDBEntry object from the database
951
952   // check if query's path and runRange are valid
953   // query is invalid also if version is not specified and subversion is!
954   if (!query.IsValid()) {
955     AliError(Form("Invalid query: %s", query.ToString().Data()));
956     return NULL;
957   }
958
959   // query is not specified if path contains wildcard or run range= [-1,-1]
960   if (!query.IsSpecified()) {
961     AliError(Form("Unspecified query: %s",
962           query.ToString().Data()));
963     return NULL;
964   }
965
966   if(fLock && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun()))
967     AliFatal("Lock is ON: cannot use different run number than the internal one!");
968
969   if(fCache && !(fRun >= query.GetFirstRun() && fRun <= query.GetLastRun()))
970     AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
971
972   AliCDBEntry *entry=0;
973
974   // first look into map of cached objects
975   if(fCache && query.GetFirstRun() == fRun)
976     entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
977   if(entry) {
978     AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
979     return entry;
980   }
981
982   // if snapshot flag is set, try getting from the snapshot
983   // but in the case a specific storage is specified for this path
984   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
985   if(!aPar){
986     if(fSnapshotMode && query.GetFirstRun() == fRun)
987     {
988       entry = GetEntryFromSnapshot(query.GetPath());
989       if(entry) {
990         AliInfo(Form("Object \"%s\" retrieved from the snapshot.",query.GetPath().Data()));
991         if(query.GetFirstRun() == fRun) // no need to check fCache, fSnapshotMode not possible otherwise
992           CacheEntry(query.GetPath(), entry);
993
994         if(!fIds->Contains(&entry->GetId()))
995           fIds->Add(entry->GetId().Clone());
996
997         return entry;
998       }
999     }
1000   }
1001
1002   // Entry is not in cache (and, in case we are in snapshot mode, not in the snapshot either)
1003   // => retrieve it from the storage and cache it!!
1004   if(!fDefaultStorage) {
1005     AliError("No storage set!");
1006     return NULL;
1007   }
1008
1009   AliCDBStorage *aStorage=0;
1010   if(aPar) {
1011     aStorage=GetStorage(aPar);
1012     TString str = aPar->GetURI();
1013     AliDebug(2,Form("Looking into storage: %s",str.Data()));
1014   } else {
1015     aStorage=GetDefaultStorage();
1016     AliDebug(2,"Looking into default storage");
1017   }
1018
1019   entry = aStorage->Get(query);
1020
1021   if(entry && fCache && (query.GetFirstRun()==fRun || forceCaching)){
1022     CacheEntry(query.GetPath(), entry);
1023   }
1024
1025   if(entry && !fIds->Contains(&entry->GetId())){
1026     fIds->Add(entry->GetId().Clone());
1027   }
1028
1029
1030   return entry;
1031
1032 }
1033
1034 //_____________________________________________________________________________
1035 AliCDBEntry* AliCDBManager::GetEntryFromSnapshot(const char* path) {
1036 // get the entry from the open snapshot file
1037
1038   TString sPath(path);
1039   sPath.ReplaceAll("/","*");
1040   if(!fSnapshotFile){
1041     AliError("No snapshot file is open!");
1042     return 0;
1043   }
1044   AliCDBEntry *entry = dynamic_cast<AliCDBEntry*>(fSnapshotFile->Get(sPath.Data()));
1045   if(!entry){
1046     AliDebug(2,Form("Cannot get a CDB entry for \"%s\" from snapshot file",path));
1047     return 0;
1048   }
1049
1050   return entry;
1051 }
1052
1053 //_____________________________________________________________________________
1054 Bool_t AliCDBManager::SetSnapshotMode(const char* snapshotFileName) {
1055 // set the manager in snapshot mode
1056
1057   if(!fCache){
1058     AliError("Cannot set the CDB manage in snapshot mode if the cache is not active!");
1059     return kFALSE;
1060   }
1061
1062   //open snapshot file
1063   TString snapshotFile(snapshotFileName);
1064   if(snapshotFile.BeginsWith("alien://")){
1065     if(!gGrid) {
1066       TGrid::Connect("alien://","");
1067       if(!gGrid) {
1068         AliError("Connection to alien failed!");
1069         return kFALSE;
1070       }
1071     }
1072   }
1073
1074   fSnapshotFile = TFile::Open(snapshotFileName);
1075   if (!fSnapshotFile || fSnapshotFile->IsZombie()){
1076     AliError(Form("Cannot open file %s",snapshotFileName));
1077     return kFALSE;
1078   }
1079
1080   AliInfo("The CDB manager is set in snapshot mode!");
1081   fSnapshotMode = kTRUE;
1082   return kTRUE;
1083
1084 }
1085
1086 //_____________________________________________________________________________
1087 const char* AliCDBManager::GetURI(const char* path) {
1088 // return the URI of the storage where to look for path
1089
1090   if(!IsDefaultStorageSet()) return 0;
1091
1092   AliCDBParam *aPar=SelectSpecificStorage(path);
1093
1094   if(aPar) {
1095     return aPar->GetURI().Data();
1096
1097   } else {
1098     return GetDefaultStorage()->GetURI().Data();
1099   }
1100
1101   return 0;
1102 }
1103
1104 //_____________________________________________________________________________
1105 Int_t AliCDBManager::GetStartRunLHCPeriod(){
1106 // get the first run of validity
1107 // for the current period
1108 // if set
1109   if(fStartRunLHCPeriod==-1)
1110     AliWarning("Run-range not yet set for the current LHC period.");
1111   return fStartRunLHCPeriod;
1112 }
1113
1114 //_____________________________________________________________________________
1115 Int_t AliCDBManager::GetEndRunLHCPeriod(){
1116 // get the last run of validity
1117 // for the current period
1118 // if set
1119   if(fEndRunLHCPeriod==-1)
1120     AliWarning("Run-range not yet set for the current LHC period.");
1121   return fEndRunLHCPeriod;
1122 }
1123
1124 //_____________________________________________________________________________
1125 TString AliCDBManager::GetLHCPeriod(){
1126 // get the current LHC period string
1127 //
1128   if(fLHCPeriod.IsWhitespace() || fLHCPeriod.IsNull())
1129     AliWarning("LHC period (OCDB folder) not yet set");
1130   return fLHCPeriod;
1131 }
1132
1133 //_____________________________________________________________________________
1134 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path, Int_t runNumber,
1135     Int_t version, Int_t subVersion) {
1136   // get the AliCDBId of the valid object from the database (does not retrieve the object)
1137   // User must delete returned object!
1138
1139   if(runNumber < 0){
1140     // RunNumber is not specified. Try with fRun
1141     if (fRun < 0){
1142       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
1143       return NULL;
1144     }
1145     runNumber = fRun;
1146   }
1147
1148   return GetId(AliCDBId(path, runNumber, runNumber, version, subVersion));
1149 }
1150
1151 //_____________________________________________________________________________
1152 AliCDBId* AliCDBManager::GetId(const AliCDBPath& path,
1153     const AliCDBRunRange& runRange, Int_t version,
1154     Int_t subVersion) {
1155   // get the AliCDBId of the valid object from the database (does not retrieve the object)
1156   // User must delete returned object!
1157
1158   return GetId(AliCDBId(path, runRange, version, subVersion));
1159 }
1160
1161 //_____________________________________________________________________________
1162 AliCDBId* AliCDBManager::GetId(const AliCDBId& query) {
1163 // get the AliCDBId of the valid object from the database (does not retrieve the object)
1164 // User must delete returned object!
1165
1166   if(!fDefaultStorage) {
1167     AliError("No storage set!");
1168     return NULL;
1169   }
1170
1171   // check if query's path and runRange are valid
1172   // query is invalid also if version is not specified and subversion is!
1173   if (!query.IsValid()) {
1174     AliError(Form("Invalid query: %s", query.ToString().Data()));
1175     return NULL;
1176   }
1177
1178   // query is not specified if path contains wildcard or run range= [-1,-1]
1179   if (!query.IsSpecified()) {
1180     AliError(Form("Unspecified query: %s",
1181           query.ToString().Data()));
1182     return NULL;
1183   }
1184
1185   if(fCache && query.GetFirstRun() != fRun)
1186     AliWarning("Run number explicitly set in query: CDB cache temporarily disabled!");
1187
1188   AliCDBEntry* entry = 0;
1189
1190   // first look into map of cached objects
1191   if(fCache && query.GetFirstRun() == fRun)
1192     entry = (AliCDBEntry*) fEntryCache.GetValue(query.GetPath());
1193
1194   if(entry) {
1195     AliDebug(2, Form("Object %s retrieved from cache !!",query.GetPath().Data()));
1196     return dynamic_cast<AliCDBId*> (entry->GetId().Clone());
1197   }
1198
1199   // Entry is not in cache -> retrieve it from CDB and cache it!!
1200   AliCDBStorage *aStorage=0;
1201   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
1202
1203   if(aPar) {
1204     aStorage=GetStorage(aPar);
1205     TString str = aPar->GetURI();
1206     AliDebug(2,Form("Looking into storage: %s",str.Data()));
1207
1208   } else {
1209     aStorage=GetDefaultStorage();
1210     AliDebug(2,"Looking into default storage");
1211   }
1212
1213   return aStorage->GetId(query);
1214
1215 }
1216
1217 //_____________________________________________________________________________
1218 TList* AliCDBManager::GetAll(const AliCDBPath& path, Int_t runNumber,
1219     Int_t version, Int_t subVersion) {
1220   // get multiple AliCDBEntry objects from the database
1221
1222   if(runNumber < 0){
1223     // RunNumber is not specified. Try with fRun
1224     if (fRun < 0){
1225       AliError("Run number neither specified in query nor set in AliCDBManager! Use AliCDBManager::SetRun.");
1226       return NULL;
1227     }
1228     runNumber = fRun;
1229   }
1230
1231   return GetAll(AliCDBId(path, runNumber, runNumber, version,   
1232         subVersion));
1233 }
1234
1235 //_____________________________________________________________________________
1236 TList* AliCDBManager::GetAll(const AliCDBPath& path,
1237     const AliCDBRunRange& runRange, Int_t version, Int_t subVersion) {
1238   // get multiple AliCDBEntry objects from the database
1239
1240   return GetAll(AliCDBId(path, runRange, version, subVersion));
1241 }
1242
1243 //_____________________________________________________________________________
1244 TList* AliCDBManager::GetAll(const AliCDBId& query) {
1245 // get multiple AliCDBEntry objects from the database
1246 // Warning: this method works correctly only for queries of the type "Detector/*"
1247 //              and not for more specific queries e.g. "Detector/Calib/*" !
1248 // Warning #2: Entries are cached, but GetAll will keep on retrieving objects from OCDB!
1249 //              To get an object from cache use Get() function
1250
1251   if(!fDefaultStorage) {
1252     AliError("No storage set!");
1253     return NULL;
1254   }
1255
1256   if (!query.IsValid()) {
1257     AliError(Form("Invalid query: %s", query.ToString().Data()));
1258     return NULL;
1259   }
1260
1261   if((fSpecificStorages.GetEntries()>0) && query.GetPath().BeginsWith('*')){
1262     // if specific storages are active a query with "*" is ambiguous
1263     AliError("Query too generic in this context!");
1264     return NULL;
1265   }
1266
1267   if (query.IsAnyRange()) {
1268     AliError(Form("Unspecified run or runrange: %s",
1269           query.ToString().Data()));
1270     return NULL;
1271   }
1272
1273   if(fLock && query.GetFirstRun() != fRun)
1274     AliFatal("Lock is ON: cannot use different run number than the internal one!");
1275
1276   AliCDBParam *aPar=SelectSpecificStorage(query.GetPath());
1277
1278   AliCDBStorage *aStorage;
1279   if(aPar) {
1280     aStorage=GetStorage(aPar);
1281     AliDebug(2,Form("Looking into storage: %s", aPar->GetURI().Data()));
1282
1283   } else {
1284     aStorage=GetDefaultStorage();
1285     AliDebug(2,Form("Looking into default storage: %s", aStorage->GetURI().Data()));
1286   }
1287
1288   TList *result = 0;
1289   if(aStorage) result = aStorage->GetAll(query);
1290   if(!result) return 0;
1291
1292   // loop on result to check whether entries should be re-queried with specific storages
1293   if(fSpecificStorages.GetEntries()>0 && ! (fSpecificStorages.GetEntries() == 1 && aPar)) {
1294     AliInfo("Now look into all other specific storages...");
1295
1296     TIter iter(result);
1297     AliCDBEntry* chkEntry=0;
1298
1299     while((chkEntry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
1300       AliCDBId& chkId = chkEntry->GetId();
1301       AliDebug(2, Form("Checking id %s ", chkId.GetPath().Data()));
1302       AliCDBParam *chkPar=SelectSpecificStorage(chkId.GetPath());
1303       if (!chkPar || aPar == chkPar) continue;
1304       AliCDBStorage *chkStorage = GetStorage(chkPar);
1305       AliDebug(2, Form("Found specific storage! %s", chkPar->GetURI().Data()));
1306
1307       AliCDBEntry *newEntry=0;
1308       chkId.SetRunRange(query.GetFirstRun(), query.GetLastRun());
1309       chkId.SetVersion(query.GetVersion());
1310       chkId.SetSubVersion(query.GetSubVersion());
1311
1312       if(chkStorage) newEntry = chkStorage->Get(chkId);
1313       if(!newEntry) continue;
1314
1315       // object is found in specific storage: replace entry in the result list!
1316       chkEntry->SetOwner(1);
1317       delete result->Remove(chkEntry);
1318       result->AddFirst(newEntry);
1319     }
1320
1321     Int_t nEntries = result->GetEntries();
1322     AliInfo("After look into other specific storages, result list is:");
1323     for(int i=0; i<nEntries;i++){
1324       AliCDBEntry *entry = (AliCDBEntry*) result->At(i);
1325       AliInfo(Form("%s",entry->GetId().ToString().Data()));
1326     }
1327   }
1328
1329   // caching entries
1330   TIter iter(result);
1331   AliCDBEntry* entry=0;
1332   while((entry = dynamic_cast<AliCDBEntry*> (iter.Next()))){
1333
1334     if(!fIds->Contains(&entry->GetId())){
1335       fIds->Add(entry->GetId().Clone());
1336     }
1337     if(fCache && (query.GetFirstRun() == fRun)){
1338       CacheEntry(entry->GetId().GetPath(), entry);
1339     }
1340   }
1341
1342
1343   return result;
1344 }
1345
1346 //_____________________________________________________________________________
1347 Bool_t AliCDBManager::Put(TObject* object, const AliCDBId& id, AliCDBMetaData* metaData, const char* mirrors, DataType type){
1348 // store an AliCDBEntry object into the database
1349
1350   if (object==0x0) {
1351     AliError("Null Entry! No storage will be done!");
1352     return kFALSE;
1353   }
1354
1355   AliCDBEntry anEntry(object, id, metaData);
1356   return Put(&anEntry, mirrors, type);
1357
1358 }
1359
1360
1361 //_____________________________________________________________________________
1362 Bool_t AliCDBManager::Put(AliCDBEntry* entry, const char* mirrors, DataType type){
1363 // store an AliCDBEntry object into the database
1364
1365   if(type == kPrivate && !fDefaultStorage) {
1366     AliError("No storage set!");
1367     return kFALSE;
1368   }
1369
1370   if (!entry){
1371     AliError("No entry!");
1372     return kFALSE;
1373   }
1374
1375   if (entry->GetObject()==0x0){
1376     AliError("No valid object in CDB entry!");
1377     return kFALSE;
1378   }
1379
1380   if (!entry->GetId().IsValid()) {
1381     AliError(Form("Invalid entry ID: %s",
1382           entry->GetId().ToString().Data()));
1383     return kFALSE;
1384   }     
1385
1386   if (!entry->GetId().IsSpecified()) {
1387     AliError(Form("Unspecified entry ID: %s",
1388           entry->GetId().ToString().Data()));
1389     return kFALSE;
1390   }
1391
1392   AliCDBId id = entry->GetId();
1393   AliCDBParam *aPar = SelectSpecificStorage(id.GetPath());
1394
1395   AliCDBStorage *aStorage=0;
1396
1397   if(aPar) {
1398     aStorage=GetStorage(aPar);
1399   } else {
1400     switch(type){
1401       case kCondition:
1402         aStorage = GetStorage(fCondParam);
1403         break;
1404       case kReference:
1405         aStorage = GetStorage(fRefParam);
1406         break;
1407       case kPrivate:
1408         aStorage = GetDefaultStorage();
1409         break;
1410     }
1411   }
1412
1413   AliDebug(2,Form("Storing object into storage: %s", aStorage->GetURI().Data()));
1414
1415   TString strMirrors(mirrors);
1416   Bool_t result = kFALSE;
1417   if(!strMirrors.IsNull() && !strMirrors.IsWhitespace())
1418     result = aStorage->Put(entry, mirrors, type);
1419   else
1420     result = aStorage->Put(entry, "", type);
1421
1422   if(fRun >= 0) QueryCDB();
1423
1424   return result;
1425
1426
1427 }
1428
1429 //_____________________________________________________________________________
1430 void AliCDBManager::SetMirrorSEs(const char* mirrors) {
1431 // set mirror Storage Elements for the default storage, if it is of type "alien"
1432   if(fDefaultStorage->GetType() != "alien"){
1433     AliInfo("The default storage is not of type \"alien\". Settings for Storage Elements are not taken into account!");
1434     return;
1435   }
1436   fDefaultStorage->SetMirrorSEs(mirrors);
1437 }
1438
1439 //_____________________________________________________________________________
1440 const char* AliCDBManager::GetMirrorSEs() const {
1441 // get mirror Storage Elements for the default storage, if it is of type "alien"
1442   if(fDefaultStorage->GetType() != "alien"){
1443     AliInfo("The default storage is not of type \"alien\". Settings for Storage Elements are not taken into account!");
1444     return "";
1445   }
1446   return fDefaultStorage->GetMirrorSEs();
1447 }
1448
1449 //_____________________________________________________________________________
1450 void AliCDBManager::CacheEntry(const char* path, AliCDBEntry* entry) {
1451 // cache AliCDBEntry. Cache is valid until run number is changed.
1452
1453   AliCDBEntry *chkEntry = dynamic_cast<AliCDBEntry*> (fEntryCache.GetValue(path));
1454
1455   if(chkEntry) {
1456     AliDebug(2, Form("Object %s already in cache !!", path));
1457     return;
1458   } else {
1459     AliDebug(2,Form("Caching entry %s", path));
1460   }
1461
1462   fEntryCache.Add(new TObjString(path), entry);
1463   AliDebug(2,Form("Cache entries: %d", fEntryCache.GetEntries()));
1464
1465 }
1466
1467 //_____________________________________________________________________________
1468 void AliCDBManager::Print(Option_t* /*option*/) const {
1469 // Print list of active storages and their URIs
1470
1471   TString output=Form("Run number = %d; ",fRun);
1472   output += "Cache is ";
1473   if(!fCache) output += "NOT ";
1474   output += Form("ACTIVE; Number of active storages: %d\n",fActiveStorages.GetEntries());
1475
1476   if(fDefaultStorage) {
1477     output += Form("\t*** Default Storage URI: \"%s\"\n",fDefaultStorage->GetURI().Data());
1478     //          AliInfo(output.Data());
1479   }
1480   if(fSpecificStorages.GetEntries()>0) {
1481     TIter iter(fSpecificStorages.GetTable());
1482     TPair *aPair=0;
1483     Int_t i=1;
1484     while((aPair = (TPair*) iter.Next())){
1485       output += Form("\t*** Specific storage %d: Path \"%s\" -> URI \"%s\"\n",
1486           i++, ((TObjString*) aPair->Key())->GetName(),
1487           ((AliCDBParam*) aPair->Value())->GetURI().Data());
1488     }
1489   }
1490   if(fDrainStorage) {
1491     output += Form("*** Drain Storage URI: %s\n",fDrainStorage->GetURI().Data());
1492   }
1493   AliInfo(output.Data());
1494 }
1495
1496 //_____________________________________________________________________________
1497 void AliCDBManager::SetRun(Int_t run) {
1498 // Sets current run number.
1499 // When the run number changes the caching is cleared.
1500
1501   if(fRun == run)
1502     return;
1503
1504   if(fLock && fRun >= 0) {
1505     AliFatal("Lock is ON, cannot reset run number!");
1506   }     
1507
1508   fRun = run;
1509
1510   if (fRaw) {
1511     // here the LHCPeriod xml file is parsed; the string containing the correct period is returned; the default storage is set
1512     if (fStartRunLHCPeriod <= run && fEndRunLHCPeriod >= run){
1513       AliInfo("LHCPeriod alien folder for current run already in memory");
1514     }else{
1515       SetDefaultStorageFromRun(run);
1516       if(fEntryCache.GetEntries()!=0) ClearCache();
1517       return;
1518     }
1519   }
1520   ClearCache();
1521   QueryCDB();
1522 }
1523
1524 //_____________________________________________________________________________
1525 void AliCDBManager::ClearCache(){
1526 // clear AliCDBEntry cache
1527
1528   AliDebug(2, Form("Cache entries to be deleted: %d",fEntryCache.GetEntries()));
1529
1530   /*
1531   // To clean entries one by one
1532   TIter iter(fEntryCache.GetTable());
1533   TPair* pair=0;
1534   while((pair= dynamic_cast<TPair*> (iter.Next()))){
1535
1536   TObjString* key = dynamic_cast<TObjString*> (pair->Key());
1537   AliCDBEntry* entry = dynamic_cast<AliCDBEntry*> (pair->Value());
1538   AliDebug(2, Form("Deleting entry: %s", key->GetName()));
1539   if (entry) delete entry;
1540   delete fEntryCache.Remove(key);
1541   }
1542   */
1543   fEntryCache.DeleteAll();
1544   AliDebug(2, Form("After deleting - Cache entries: %d",fEntryCache.GetEntries()));
1545 }
1546
1547 //_____________________________________________________________________________
1548 void AliCDBManager::UnloadFromCache(const char* path){
1549 // unload cached object
1550 // that is remove the entry from the cache and the id from the list of ids
1551 //
1552   if(!fActiveStorages.GetEntries()) {
1553     AliDebug(2, Form("No active storages. Object \"%s\" is not unloaded from cache", path));
1554     return;
1555   }
1556
1557   AliCDBPath queryPath(path);
1558   if(!queryPath.IsValid()) return;
1559
1560   if(!queryPath.IsWildcard()) { // path is not wildcard, get it directly from the cache and unload it!
1561     if(fEntryCache.Contains(path)){
1562       AliDebug(2, Form("Unloading object \"%s\" from cache and from list of ids", path));
1563       TObjString pathStr(path);
1564       delete fEntryCache.Remove(&pathStr);
1565       // we do not remove from the list of Id's (it's not very coherent but we leave the
1566       // id for the benefit of the userinfo)
1567       /*
1568          TIter iter(fIds);
1569          AliCDBId *id = 0;
1570          while((id = dynamic_cast<AliCDBId*> (iter.Next()))){
1571          if(queryPath.Comprises(id->GetPath()))
1572          delete fIds->Remove(id);
1573          }*/
1574     } else {
1575       AliWarning(Form("Cache does not contain object \"%s\"!", path));
1576     }
1577     AliDebug(2, Form("Cache entries: %d",fEntryCache.GetEntries()));
1578     return;
1579   }
1580
1581   // path is wildcard: loop on the cache and unload all comprised objects!
1582   TIter iter(fEntryCache.GetTable());
1583   TPair* pair = 0;
1584   Int_t removed=0;
1585
1586   while((pair = dynamic_cast<TPair*> (iter.Next()))){
1587     AliCDBPath entryPath = pair->Key()->GetName();
1588     if(queryPath.Comprises(entryPath)) {
1589       AliDebug(2, Form("Unloading object \"%s\" from cache and from list of ids", entryPath.GetPath().Data()));
1590       TObjString pathStr(entryPath.GetPath());
1591       delete fEntryCache.Remove(&pathStr);
1592       removed++;
1593
1594       // we do not remove from the list of Id's (it's not very coherent but we leave the
1595       // id for the benefit of the userinfo)
1596       /*
1597          TIter iterids(fIds);
1598          AliCDBId *anId = 0;
1599          while((anId = dynamic_cast<AliCDBId*> (iterids.Next()))){
1600          AliCDBPath aPath = anId->GetPath();
1601          TString aPathStr = aPath.GetPath();
1602          if(queryPath.Comprises(aPath)) {
1603          delete fIds->Remove(anId);
1604          }
1605          }*/
1606     }
1607   }
1608   AliDebug(2,Form("Cache entries and ids removed: %d   Remaining: %d",removed,fEntryCache.GetEntries()));
1609 }
1610
1611 //_____________________________________________________________________________
1612 void AliCDBManager::DestroyActiveStorages() {
1613 // delete list of active storages
1614
1615   fActiveStorages.DeleteAll();
1616   fSpecificStorages.DeleteAll();
1617 }
1618
1619 //_____________________________________________________________________________
1620 void AliCDBManager::DestroyActiveStorage(AliCDBStorage* /*storage*/) {
1621 // destroys active storage
1622
1623   /*
1624      TIter iter(fActiveStorages.GetTable());
1625      TPair* aPair;
1626      while ((aPair = (TPair*) iter.Next())) {
1627      if(storage == (AliCDBStorage*) aPair->Value())
1628      delete fActiveStorages.Remove(aPair->Key());
1629      storage->Delete(); storage=0x0;
1630      }
1631      */
1632
1633 }
1634
1635 //_____________________________________________________________________________
1636 void AliCDBManager::QueryCDB() {
1637 // query default and specific storages for files valid for fRun. Every storage loads the Ids into its list.
1638
1639   if (fRun < 0){
1640     AliError("Run number not yet set! Use AliCDBManager::SetRun.");
1641     return;
1642   }
1643   if (!fDefaultStorage){
1644     AliError("Default storage is not set! Use AliCDBManager::SetDefaultStorage");
1645     return;
1646   }
1647   if(fDefaultStorage->GetType() == "alien" || fDefaultStorage->GetType() == "local"){
1648     fDefaultStorage->QueryCDB(fRun);
1649   //} else {
1650   //    AliDebug(2,"Skipping query for valid files, it used only in grid...");
1651   }
1652
1653   TIter iter(&fSpecificStorages);
1654   TObjString *aCalibType=0;
1655   AliCDBParam* aPar=0;
1656   while((aCalibType = dynamic_cast<TObjString*> (iter.Next()))){
1657     aPar = (AliCDBParam*) fSpecificStorages.GetValue(aCalibType);
1658     if(aPar) {
1659       AliDebug(2,Form("Querying specific storage %s",aCalibType->GetName()));
1660       AliCDBStorage *aStorage = GetStorage(aPar);
1661       if(aStorage->GetType() == "alien"){
1662         aStorage->QueryCDB(fRun,aCalibType->GetName());
1663       } else {
1664         AliDebug(2,
1665             "Skipping query for valid files, it is used only in grid...");
1666       }
1667     }
1668   }
1669 }
1670
1671 //______________________________________________________________________________________________
1672 const char* AliCDBManager::GetDataTypeName(DataType type) {
1673 // returns the name (string) of the data type
1674
1675   switch (type){
1676     case kCondition: return "Conditions";
1677     case kReference: return "Reference";
1678     case kPrivate: return "Private";
1679   }
1680   return 0;
1681
1682 }
1683
1684 //______________________________________________________________________________________________
1685 Bool_t AliCDBManager::DiffObjects(const char *cdbFile1, const char *cdbFile2) const {
1686 // Compare byte-by-byte the objects contained in the CDB entry in two different files,
1687 // whose name is passed as input
1688 // Return value:
1689 //   kTRUE - in case the content of the OCDB object (persistent part) is exactly the same
1690 //   kFALSE - otherwise
1691
1692   TString f1Str(cdbFile1);
1693   TString f2Str(cdbFile2);
1694   if (!gGrid && ( f1Str.BeginsWith("alien://") || f2Str.BeginsWith("alien://") ))
1695     TGrid::Connect("alien://");
1696
1697   TFile * f1 = TFile::Open(cdbFile1);
1698   if (!f1){
1699     Printf("Cannot open file \"%s\"",cdbFile1);
1700     return kFALSE;
1701   }
1702   TFile * f2 = TFile::Open(cdbFile2);
1703   if (!f2){
1704     Printf("Cannot open file \"%s\"",cdbFile2);
1705     return kFALSE;
1706   }
1707
1708   AliCDBEntry * entry1 = (AliCDBEntry*)f1->Get("AliCDBEntry");
1709   if (!entry1){
1710     Printf("Cannot get CDB entry from file \"%s\"",cdbFile1);
1711     return kFALSE;
1712   }
1713   AliCDBEntry * entry2 = (AliCDBEntry*)f2->Get("AliCDBEntry");
1714   if (!entry2){
1715     Printf("Cannot get CDB entry from file \"%s\"",cdbFile2);
1716     return kFALSE;
1717   }
1718
1719   // stream the two objects in the buffer of two TMessages
1720   TObject* object1 = entry1->GetObject();
1721   TObject* object2 = entry2->GetObject();
1722   TMessage * file1 = new TMessage(TBuffer::kWrite);
1723   file1->WriteObject(object1);
1724   Int_t size1 = file1->Length();
1725   TMessage * file2 = new TMessage(TBuffer::kWrite);
1726   file2->WriteObject(object2);
1727   Int_t size2 = file2->Length();
1728   if (size1!=size2){
1729     Printf("Problem 2:  OCDB entry of different size (%d,%d)",size1,size2);
1730     return kFALSE;
1731   }
1732
1733   // if the two buffers have the same size, check that they are the same byte-by-byte
1734   Int_t countDiff=0;
1735   char* buf1 = file1->Buffer();
1736   char* buf2 = file2->Buffer();
1737   //for (Int_t i=0; i<size1; i++)    if (file1->Buffer()[i]!=file2->Buffer()[i]) countDiff++;
1738   for(Int_t i=0; i<size1; i++)
1739     if (buf1[i]!=buf2[i]) countDiff++;
1740
1741   if (countDiff>0){
1742     Printf("The CDB objects differ by %d bytes.", countDiff);
1743     return kFALSE;
1744   }
1745
1746   Printf("The CDB objects are the same in the two files.");
1747   return kTRUE;
1748 }
1749
1750 //______________________________________________________________________________________________
1751 void AliCDBManager::InitShortLived() {
1752 // Init the list of short-lived objects
1753 // currently disabled
1754
1755   fShortLived=0x0;
1756
1757   //    fShortLived = new TList();
1758   //    fShortLived->SetOwner(1);
1759   //
1760   //    fShortLived->Add(new TObjString("EMCAL/Calib/Data"));
1761   //
1762   //    fShortLived->Add(new TObjString("HMPID/Calib/Nmean"));
1763   //    fShortLived->Add(new TObjString("HMPID/Calib/Qthre"));
1764   //
1765   //    fShortLived->Add(new TObjString("ITS/Calib/CalibSPD"));
1766   //
1767   //    fShortLived->Add(new TObjString("MUON/Calib/Gains"));
1768   //    fShortLived->Add(new TObjString("MUON/Calib/HV"));
1769   //    fShortLived->Add(new TObjString("MUON/Calib/Pedestals"));
1770   //
1771   //    fShortLived->Add(new TObjString("PHOS/Calib/CpvGainPedestals"));
1772   //    fShortLived->Add(new TObjString("PHOS/Calib/EmcGainPedestals"));
1773   //
1774   //    fShortLived->Add(new TObjString("PMD/Calib/Data"));
1775   //
1776   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberGainFactor"));
1777   //    fShortLived->Add(new TObjString("TRD/Calib/LocalGainFactor"));
1778   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberT0"));
1779   //    fShortLived->Add(new TObjString("TRD/Calib/LocalT0"));
1780   //    fShortLived->Add(new TObjString("TRD/Calib/ChamberVdrift"));
1781   //    fShortLived->Add(new TObjString("TRD/Calib/LocalVdrift"));
1782   //
1783   //    fShortLived->Add(new TObjString("ZDC/Calib/Data"));
1784
1785 }
1786
1787 //______________________________________________________________________________________________
1788 Bool_t AliCDBManager::IsShortLived(const char* path) {
1789 // returns the name (string) of the data type
1790
1791   if(!fShortLived) return kFALSE;
1792
1793   AliCDBPath aPath(path);
1794   if(!aPath.IsValid()){
1795     AliError(Form("Not a valid path: %s", path));
1796     return kFALSE;
1797   }
1798
1799   return fShortLived->Contains(path);
1800
1801 }
1802
1803 //______________________________________________________________________________________________
1804 ULong64_t AliCDBManager::SetLock(Bool_t lock, ULong64_t key){
1805 // To lock/unlock user must provide the key. A new key is provided after
1806 // each successful lock. User should always backup the returned key and
1807 // use it on next access.
1808   if (fLock == lock) return 0;  // nothing to be done
1809   if (lock) {
1810     // User wants to lock - check his identity
1811     if (fKey) {
1812       // Lock has a user - check his key
1813       if (fKey != key) {
1814         AliFatal("Wrong key provided to lock CDB. Please remove CDB lock access from your code !");
1815         return 0;
1816       }
1817     }
1818     // Provide new key
1819     fKey = gSystem->Now();
1820     fLock = kTRUE;
1821     return fKey;
1822   }
1823   // User wants to unlock - check the provided key
1824   if (key != fKey) {
1825     AliFatal("Lock is ON: wrong key provided");
1826     return 0;
1827   }
1828   fLock = kFALSE;
1829   return key;
1830 }
1831
1832 ///////////////////////////////////////////////////////////
1833 // AliCDBManager Parameter class                         //
1834 // interface to specific AliCDBParameter class           //
1835 // (AliCDBGridParam, AliCDBLocalParam, AliCDBDumpParam)  //
1836 ///////////////////////////////////////////////////////////
1837
1838 AliCDBParam::AliCDBParam():
1839   fType(),
1840   fURI()
1841 {
1842   // constructor
1843
1844 }
1845
1846 //_____________________________________________________________________________
1847 AliCDBParam::~AliCDBParam() {
1848   // destructor
1849
1850 }
1851