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