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