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