GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4DirProxy.cxx
Go to the documentation of this file.
1 // $Id$
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4DirProxy.h"
15 
16 #include "TKey.h"
17 #include "TROOT.h"
18 #include "TH1.h"
19 #include "TTree.h"
20 #include "TFile.h"
21 #include "TCanvas.h"
22 #include "THStack.h"
23 
24 #include "TGo4ObjectProxy.h"
25 #include "TGo4TreeProxy.h"
26 #include "TGo4CanvasProxy.h"
27 #include "TGo4HStackProxy.h"
28 #include "TGo4Slot.h"
29 
30 class TGo4KeyAccess : public TGo4Access {
31  public:
32  TGo4KeyAccess(TDirectory *dir, TKey *key) : TGo4Access(), fDir(dir), fKey(key) {}
33 
34  Bool_t CanGetObject() const override
35  { return kTRUE; }
36 
37  Bool_t GetObject(TObject *&obj, Bool_t &owner) const override
38  {
39  TClass *cl = gROOT->GetClass(fKey->GetClassName());
40  if (cl && !cl->IsLoaded()) {
41  obj = nullptr;
42  owner = kFALSE;
43  return kFALSE;
44  }
45 
46  owner = kTRUE;
47  fDir->cd();
48  obj = fKey->ReadObj();
49  if (!obj) return kFALSE;
50 
51  if (obj->InheritsFrom(TH1::Class()) || obj->InheritsFrom(TTree::Class())) owner = kFALSE; else
52  if (obj->InheritsFrom(TCanvas::Class())) { fDir->Add(obj); owner = kFALSE; }
53  return kTRUE;
54  }
55 
56  const char *GetObjectName() const override
57  { return fKey->GetName(); }
58 
59  const char *GetObjectClassName() const override
60  { return fKey->GetClassName(); }
61 
62  private:
63  TDirectory *fDir{nullptr};
64  TKey *fKey{nullptr};
65 };
66 
67 // ************************************************************************
68 
70  protected:
71  TDirectory *fDir{nullptr};
72  Bool_t fReadRight{kFALSE};
73  TIterator *fIter{nullptr};
74  Bool_t fIsKeyIter{kFALSE};
75  TObject *fCurrent{nullptr};
76  TString fNameBuf;
77 
78  public:
79  TGo4DirLevelIter(TDirectory *dir, Bool_t readright) :
80  TGo4LevelIter(),
81  fDir(dir),
82  fReadRight(readright),
83  fIter(nullptr),
84  fIsKeyIter(kFALSE),
85  fCurrent(nullptr),
86  fNameBuf()
87  {
88  fIter = fDir->GetListOfKeys()->MakeIterator();
89  fIsKeyIter = kTRUE;
90  }
91 
93  {
94  if (fIter) delete fIter;
95  }
96 
97  Bool_t next() override
98  {
99  Bool_t donext = kTRUE;
100 
101  while (donext) {
102 
103  fCurrent = fIter->Next();
104 
105  if (!fCurrent) {
106  if(fIsKeyIter) {
107  delete fIter;
108  fIter = fDir->GetList()->MakeIterator();
109  fIsKeyIter = kFALSE;
110  continue;
111  } else
112  break;
113  }
114  donext = kFALSE;
115 
116  if (!fIsKeyIter) {
117  TKey *key = fDir->FindKey(fCurrent->GetName());
118  if (key)
119  if (strcmp(fCurrent->ClassName(), key->GetClassName()) == 0) donext = kTRUE;
120  }
121  }
122  return fCurrent != nullptr;
123  }
124 
125  Bool_t IsContainerClass(TClass *cl)
126  {
127  if (!cl) return kFALSE;
128  return cl->InheritsFrom(TDirectory::Class()) ||
129  cl->InheritsFrom(TTree::Class()) ||
130  cl->InheritsFrom(TCanvas::Class()) ||
131  cl->InheritsFrom(THStack::Class());
132  }
133 
134  Bool_t isfolder() override
135  {
136  TClass *cl = nullptr;
137  if (fIsKeyIter) {
138  TKey *key = (TKey *) fCurrent;
139  TObject *obj = fDir->FindObject(key->GetName());
140  if (obj) cl = obj->IsA();
141  // if (fReadRight)
142  // cl = TGo4Proxy::GetClass(key->GetClassName());
143  } else {
144  cl = fCurrent->IsA();
145  }
146 
147  return IsContainerClass(cl);
148  }
149 
151  {
152  TObject *obj = fIsKeyIter ? fDir->Get(fCurrent->GetName()) : fCurrent;
153 
154  if (!obj) return nullptr;
155 
156  if (obj->InheritsFrom(TTree::Class()))
157  return TGo4TreeProxy::ProduceIter((TTree *)obj);
158 
159  if (obj->InheritsFrom(TCanvas::Class()))
160  return TGo4CanvasProxy::ProduceIter((TCanvas *)obj);
161 
162  if (obj->InheritsFrom(THStack::Class()))
163  return TGo4HStackProxy::ProduceIter((THStack *)obj);
164 
165  TDirectory *subdir = dynamic_cast<TDirectory *> (obj);
166  return !subdir ? nullptr : new TGo4DirLevelIter(subdir, fReadRight);
167  }
168 
169  const char *name() override
170  {
171  if (!fIsKeyIter) return fCurrent->GetName();
172  TKey *key = (TKey *) fCurrent;
173  // if (isfolder() || (key->GetCycle()==1)) return key->GetName();
174  fNameBuf.Form("%s;%d",key->GetName(),(int) key->GetCycle());
175  return fNameBuf.Data();
176  }
177 
178  const char *info() override
179  {
180  return fCurrent->GetTitle();
181  }
182 
183  Int_t sizeinfo() override
184  {
185  TClass *cl = nullptr;
186  Int_t sz = 0;
187  if (fIsKeyIter) {
188  TKey *key = (TKey *) fCurrent;
189  cl = TGo4Proxy::GetClass(key->GetClassName());
190  sz = key->GetNbytes();
191  TObject *obj = fDir->FindObject(key->GetName());
192  if (obj) sz = TGo4ObjectProxy::DefineObjectSize(obj);
193  } else {
194  cl = fCurrent->IsA();
195  sz = TGo4ObjectProxy::DefineObjectSize(fCurrent);
196  }
197  bool isdir = cl && cl->InheritsFrom(TDirectory::Class());
198  return isdir ? 0 : sz;
199  }
200 
201  Int_t GetKind() override
202  {
203  if (isfolder()) return TGo4Access::kndFolder;
204 
205  if (fIsKeyIter && fReadRight) {
206  TKey *key = (TKey *) fCurrent;
207  TClass *cl = TGo4Proxy::GetClass(key->GetClassName());
208  if (!cl) cl = gROOT->GetClass(key->GetClassName(), kTRUE, kTRUE);
209  if (IsContainerClass(cl)) return TGo4Access::kndMoreFolder;
210  }
211 
212  return TGo4Access::kndObject;
213  }
214 
215  const char *GetClassName() override
216  {
217  return fIsKeyIter ? ((TKey *) fCurrent)->GetClassName() : fCurrent->ClassName();
218  }
219 };
220 
221 //*************************************************************************
222 
224  TGo4Proxy()
225 {
226 }
227 
228 TGo4DirProxy::TGo4DirProxy(TDirectory *dir, Bool_t readright, Bool_t owner) :
229  TGo4Proxy()
230 {
231  SetDir(dir, readright, owner);
232 }
233 
235 {
236  ClearDir();
237 }
238 
239 void TGo4DirProxy::SetDir(TDirectory *dir, Bool_t readright, Bool_t owner)
240 {
241  ClearDir();
242  fDir = dir;
243  fReadRight = readright;
244  fOwner = owner;
245 }
246 
248 {
249  if (fOwner && fDir) delete fDir;
250  fDir = nullptr;
251  fOwner = kFALSE;
252 }
253 
255 {
257 }
258 
260 {
261  return fDir ? fDir->ClassName() : nullptr;
262 }
263 
265 {
266  return fDir ? fDir->GetTitle() : nullptr;
267 }
268 
270 {
271  TFile *f = dynamic_cast<TFile *> (fDir);
272  return !f ? TGo4Proxy::GetObjectSizeInfo() : f->GetSize();
273 }
274 
275 std::unique_ptr<TGo4Access> TGo4DirProxy::CreateAccess(TDirectory *dir, Bool_t readright, const char *name, TGo4Slot *browser_slot)
276 {
277  if (!dir) return nullptr;
278 
279  if (!name || !*name)
280  return std::make_unique<TGo4ObjectAccess>(dir);
281 
282  TDirectory *curdir = dir;
283  const char *curname = name;
284 
285  while (curdir && curname) {
286  const char *slash = strchr(curname,'/');
287  TString partname;
288 
289  if (!slash) {
290  partname = curname;
291  curname = nullptr;
292  } else {
293  partname.Append(curname, slash - curname);
294  curname = slash+1;
295  if (*curname == 0) curname = nullptr; // if last symbol is slash than finish searching
296  }
297 
298  char namebuf[10000];
299  Short_t cyclebuf(9999);
300  TDirectory::DecodeNameCycle(partname.Data(), namebuf, cyclebuf, sizeof(namebuf));
301 
302  TObject *obj = curdir->GetList()->FindObject(namebuf);
303  if (!obj) {
304  TKey *key = curdir->GetKey(namebuf, cyclebuf);
305  if (!key) return nullptr;
306  if (!readright)
307  return std::make_unique<TGo4KeyAccess>(curdir, key);
308  curdir->cd();
309  obj = curdir->Get(partname.Data());
310  if (obj && obj->InheritsFrom(TCanvas::Class())) curdir->Add(obj);
311  if (obj && browser_slot)
312  browser_slot->ForwardEvent(browser_slot, TGo4Slot::evObjAssigned);
313  }
314 
315  if (!obj) return nullptr;
316 
317  TTree *tr = dynamic_cast<TTree *> (obj);
318  if (tr)
319  return TGo4TreeProxy::CreateAccess(tr, curname);
320 
321  TCanvas *canv = dynamic_cast<TCanvas *> (obj);
322  if (canv)
323  return TGo4CanvasProxy::CreateAccess(canv, curname);
324 
325  THStack *hs = dynamic_cast<THStack *> (obj);
326  if (hs)
327  return TGo4HStackProxy::CreateAccess(hs, curname);
328 
329  curdir = dynamic_cast<TDirectory *>(obj);
330 
331  if (!curdir)
332  return std::make_unique<TGo4ObjectAccess>(obj);
333  }
334  return nullptr;
335 }
336 
337 TGo4LevelIter *TGo4DirProxy::ProduceIter(TDirectory *dir, Bool_t readright)
338 {
339  return new TGo4DirLevelIter(dir, readright);
340 }
341 
342 void TGo4DirProxy::WriteData(TGo4Slot *slot, TDirectory *dir, Bool_t onlyobjs)
343 {
344  if (!onlyobjs) {
345  const char *filename = nullptr;
346  if (fDir && fDir->InheritsFrom(TFile::Class()))
347  filename = fDir->GetName();
348 
349  slot->SetPar("DirProxy::FileName", filename);
350  slot->SetPar("DirProxy::gROOT", (fDir==gROOT) ? "true" : nullptr);
351  }
352 }
353 
354 void TGo4DirProxy::ReadData(TGo4Slot *slot, TDirectory *dir)
355 {
356  ClearDir();
357 
358  const char *filename = slot->GetPar("DirProxy::FileName");
359  const char *groot = slot->GetPar("DirProxy::gROOT");
360 
361  if (filename) {
362  TFile *f = TFile::Open(filename);
363  if (f) SetDir(f, kTRUE, kTRUE);
364  } else if (groot)
365  SetDir(gROOT, kFALSE, kFALSE);
366 }
367 
368 Bool_t TGo4DirProxy::UpdateObjectInFile(const char *filepath, TObject *obj)
369 {
370  if (!filepath || !fDir) return kFALSE;
371 
372  TFile *f = dynamic_cast<TFile *> (fDir);
373  if (!f) return kFALSE;
374 
375  if (f->ReOpen("UPDATE") < 0) return kFALSE;
376 
377  TString foldername, objname;
378  TGo4Slot::ProduceFolderAndName(filepath, foldername, objname);
379 
380  TDirectory *objdir = f;
381 
382  if (foldername.Length() > 0)
383  objdir = dynamic_cast<TDirectory *> (f->Get(foldername));
384 
385  char namebuf[10000];
386  Short_t cyclebuf;
387  TDirectory::DecodeNameCycle(objname.Data(), namebuf, cyclebuf, sizeof(namebuf));
388 
389  if (objdir) {
390  objdir->cd();
391  objdir->Delete(objname.Data());
392  objdir->WriteTObject(obj, namebuf, "Overwrite");
393  }
394 
395  f->ReOpen("READ");
396 
397  return kTRUE;
398 }
399 
400 Bool_t TGo4DirProxy::IsFile() const
401 {
402  return dynamic_cast<TFile *>(fDir) != nullptr;
403 }
404 
405 const char *TGo4DirProxy::GetFileName() const
406 {
407  return IsFile() ? fDir->GetName() : nullptr;
408 }
static TClass * GetClass(const char *classname, Bool_t load=kFALSE)
Definition: TGo4Proxy.cxx:73
TGo4KeyAccess(TDirectory *dir, TKey *key)
Bool_t IsFile() const
Bool_t fReadRight
Definition: TGo4DirProxy.h:26
static TGo4LevelIter * ProduceIter(TTree *tree)
const char * info() override
static TGo4LevelIter * ProduceIter(THStack *hs)
const char * GetContainedObjectInfo() override
const char * GetObjectClassName() const override
static Long_t DefineObjectSize(TObject *obj)
Int_t GetObjectKind() const override
const char * GetFileName() const
static TGo4LevelIter * ProduceIter(TCanvas *canv)
static TGo4LevelIter * ProduceIter(TDirectory *dir, Bool_t readright)
TDirectory * fDir
const char * GetContainedClassName() const override
Bool_t CanGetObject() const override
virtual Int_t GetObjectSizeInfo() const
Definition: TGo4Proxy.h:117
virtual ~TGo4DirProxy()
Int_t sizeinfo() override
Int_t GetKind() override
Bool_t next() override
TDirectory * fDir
Definition: TGo4DirProxy.h:24
Bool_t GetObject(TObject *&obj, Bool_t &owner) const override
Bool_t UpdateObjectInFile(const char *filepath, TObject *obj)
const char * GetClassName() override
static std::unique_ptr< TGo4Access > CreateAccess(TCanvas *canv, const char *name)
Bool_t isfolder() override
Bool_t fOwner
Definition: TGo4DirProxy.h:25
const char * GetPar(const char *name) const
Definition: TGo4Slot.cxx:598
static std::unique_ptr< TGo4Access > CreateAccess(TTree *tree, const char *name)
void WriteData(TGo4Slot *slot, TDirectory *dir, Bool_t onlyobjs) override
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition: TGo4Slot.cxx:646
const char * name() override
virtual ~TGo4DirLevelIter()
const char * GetObjectName() const override
void ForwardEvent(TGo4Slot *source, Int_t id, void *param=nullptr)
Definition: TGo4Slot.cxx:565
TGo4DirLevelIter(TDirectory *dir, Bool_t readright)
void SetDir(TDirectory *dir, Bool_t readright, Bool_t owner)
void ReadData(TGo4Slot *slot, TDirectory *dir) override
Bool_t IsContainerClass(TClass *cl)
void SetPar(const char *name, const char *value)
Definition: TGo4Slot.cxx:586
Int_t GetObjectSizeInfo() const override
static std::unique_ptr< TGo4Access > CreateAccess(THStack *hs, const char *name)
TGo4LevelIter * subiterator() override
static std::unique_ptr< TGo4Access > CreateAccess(TDirectory *dir, Bool_t readright, const char *name, TGo4Slot *browser_slot=nullptr)