c5dc271bb3df0a7a0b7c66edd1eddab1d464856f
[u/mrichter/AliRoot.git] / ANALYSIS / AliXMLCollection.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 /* $Id$ */
17
18 //-----------------------------------------------------------------
19 //           Implementation of the AliXMLCollection class
20 //   This is the class that creates XML collections after querying the tags
21 //   Origin: Panos Christakoglou, UOA-CERN, Panos.Christakoglou@cern.ch
22 //-----------------------------------------------------------------
23
24 //ROOT
25 #include <Riostream.h>
26 #include <TEntryList.h>
27 #include <TList.h>
28 #include <TMap.h>
29 #include <TObjArray.h>
30 #include <TObjString.h>
31 #include <TString.h>
32 #include <TXMLEngine.h>
33
34 #include "AliXMLCollection.h"
35
36 ClassImp(AliXMLCollection)
37
38 //___________________________________________________________________________
39   AliXMLCollection::AliXMLCollection() :
40     TGridCollection(),
41     fXmlFile(),
42     fEventList(0),
43     fEventListIter(0),
44     fCurrent(0),
45     fCollectionName(),
46     fout() {
47   //Default constructor
48 }
49
50 //___________________________________________________________________________
51 AliXMLCollection::AliXMLCollection(const char *localcollectionfile) {
52    // Create Alien event collection, by reading collection for the specified
53    // file.
54
55    fXmlFile = localcollectionfile;
56    fEventList = new TList();
57    fEventList->SetOwner(kTRUE);
58    fEventListIter = new TIter(fEventList);
59    fCurrent = 0;
60    if (localcollectionfile!=0) {
61      ParseXML();
62    }
63 }
64
65 //___________________________________________________________________________
66 AliXMLCollection::AliXMLCollection(const AliXMLCollection& collection):
67   TGridCollection(collection),
68   fXmlFile(collection.fXmlFile),
69   fCollectionName(collection.fCollectionName) {
70   //copy constructor
71
72   if (collection.fEventList) fEventList = new TList();
73   if (collection.fEventListIter) fEventListIter = new TIter(fEventList);
74   if (collection.fCurrent) fCurrent = 0;
75 }
76
77 //___________________________________________________________________________
78 AliXMLCollection::~AliXMLCollection() {
79   //Destructor
80   if(fEventList) delete fEventList;
81   if(fEventListIter) delete fEventListIter;
82 }
83
84 //___________________________________________________________________________
85 Bool_t AliXMLCollection::WriteHeader() {
86   //Creates the xml output file
87
88   TString xmlName = fCollectionName;
89   xmlName += ".xml";
90
91   TString collectionHeader = "<collection name=";
92   collectionHeader += "\"";
93   collectionHeader += fCollectionName;
94   collectionHeader += "\"";
95   collectionHeader += ">";
96   
97   // Open the output stream
98   fout.open(xmlName);
99   fout<<"<?xml version=\"1.0\"?>\n";
100   fout<<"<alien>\n";
101   fout<<"  "<<collectionHeader<<"\n";  
102
103   return kTRUE;
104 }
105
106 //___________________________________________________________________________
107 Bool_t AliXMLCollection::WriteBody(Int_t counter, const char* guid, const char* lfn, const char* turl, TEntryList *list) {
108   //Writes the body of the xml collection
109   TString listline;
110   for(Int_t i = 0; i < list->GetN(); i++) {
111     listline += list->GetEntry(i);
112     listline += ",";
113   }  
114   listline = listline(0,listline.Length()-1);
115
116   TString line0 = "<event name=\"";
117   line0 += counter;
118   line0 += "\">";
119   
120   TString line1 = "<file name=\"AliESDs.root\" ";
121   line1 += "guid=\"";
122   line1 += guid;
123   line1 += "\" ";
124   line1 += "lfn=\"";
125   line1 += lfn;
126   line1 += "\" ";
127   line1 += "turl=\"";
128   line1 += turl;
129   line1 += "\" ";
130   line1 += "evlist=\"";
131   line1 += listline;
132   line1 += "\"";
133   line1 += " />";
134   
135   fout<<"    "<<line0<<"\n";
136   fout<<"      "<<line1<<"\n";
137   fout<<"    </event>\n";
138   
139   return kTRUE;
140 }
141
142 //___________________________________________________________________________
143 Bool_t AliXMLCollection::Export() {
144   //Closes the stream
145   fout<<"  "<<"</collection>\n";
146   fout<<"</alien>\n";
147
148   fout.close();
149
150   return kTRUE;
151 }
152
153 //___________________________________________________________________________
154 void AliXMLCollection::Reset() {
155   // Reset file iterator.
156   
157   fEventListIter->Reset();
158   fCurrent = 0;
159 }
160
161 //___________________________________________________________________________
162 TMap *AliXMLCollection::Next() {
163   // Return next event file map.
164   
165   fCurrent = (TMap*)fEventListIter->Next();
166   return fCurrent;
167 }
168
169 //___________________________________________________________________________
170 const char *AliXMLCollection::GetTURL(const char* filename) const {
171   // Get a file's transport URL (TURL). Returns 0 in case of error.
172   
173   if (fCurrent) {
174     TMap *obj = (TMap*)fCurrent->GetValue(filename);
175     if (obj) {
176       if (obj->GetValue("turl")) {
177         return ( ((TObjString*)obj->GetValue("turl"))->GetName());
178       }
179     }
180   }
181   Error("GetTURL","cannot get TURL of file %s",filename);
182   return 0;
183 }
184
185 //___________________________________________________________________________
186 const char *AliXMLCollection::GetGUID(const char* filename) const {
187   // Get a file's transport UID. Returns 0 in case of error.
188   
189   if (fCurrent) {
190     TMap *obj = (TMap*)fCurrent->GetValue(filename);
191     if (obj) {
192       if (obj->GetValue("guid")) {
193         return ( ((TObjString*)obj->GetValue("guid"))->GetName());
194       }
195     }
196   }
197   Error("GetGUID","cannot get GUID of file %s",filename);
198   return 0;
199 }
200
201 //___________________________________________________________________________
202 TEntryList *AliXMLCollection::GetEventList(const char *filename) const {
203   // Get a file's event list. Returns 0 in case of error.
204
205   if (fCurrent) {
206     TMap *obj = (TMap *) fCurrent->GetValue(filename);
207     if (obj) {
208       if (obj->GetValue("evlist")) {
209         return ((TEntryList *) obj->GetValue("evlist"));
210       }
211     }
212   }
213   Error("GetEvList", "cannot get evelist of file %s", filename);
214   return 0;
215 }
216
217 //___________________________________________________________________________
218 Bool_t AliXMLCollection::Remove(TMap * map) {
219   // Return next event file map.
220   if (fEventList->Remove(map)) {
221     return kTRUE;
222   } else {
223     return kFALSE;
224   }
225 }
226
227 //___________________________________________________________________________
228 const char *AliXMLCollection::GetLFN(const char* ) const {
229   // Get a file's LFN. Returns 0 in case of error.
230   
231   if (fCurrent) {
232     TMap *obj = (TMap *) fCurrent->GetValue("");
233     if (obj) {
234       if (obj->GetValue("lfn")) {
235         return (((TObjString *) obj->GetValue("lfn"))->GetName());
236       }
237     }
238   }
239   Error("GetLFN", "cannot get LFN");
240   return 0;
241 }
242
243 //__________________________________________________________________________
244 Bool_t AliXMLCollection::OverlapCollection(AliXMLCollection * comparator) {
245   // return kTRUE if comparator overlaps with this
246   if ((!comparator)) return kFALSE;
247   
248  loopagain:
249   // loop over col1 and try to find it in col2
250   this->Reset();
251   // loop over all elements in reference (=this)
252   TMap *overlapmap;
253   while ((overlapmap = this->Next())) {
254     comparator->Reset();
255     Bool_t found = kFALSE;
256     // try to find in the comparator collection
257     while ((comparator->Next())) {
258       TString s1 = this->GetLFN("");
259       TString s2 = comparator->GetLFN("");
260       if (s1 == s2) {
261         found = kTRUE;
262         break;
263       }
264     }
265     if (!found) {
266       this->Remove(overlapmap);
267       goto loopagain;
268     }
269   }
270   return kTRUE;
271 }
272
273 //___________________________________________________________________________
274 AliXMLCollection *AliXMLCollection::Open(const char *localcollectionfile) {
275   // Static method used to create an Alien event collection, by reading
276   // collection for the specified file.
277   
278   AliXMLCollection *collection = new AliXMLCollection(localcollectionfile);
279   return collection;
280 }
281
282 //___________________________________________________________________________
283 void AliXMLCollection::ParseXML() {
284   // Parse event file collection XML file.
285   
286   TXMLEngine xml;
287   
288   XMLDocPointer_t xdoc = xml.ParseFile(fXmlFile);
289   if (!xdoc) {
290     Error("ParseXML","cannot parse the xml file %s",fXmlFile.Data());
291     return;
292   }
293
294   XMLNodePointer_t xalien = xml.DocGetRootElement(xdoc);
295   if (!xalien) {
296     Error("ParseXML","cannot find the <alien> tag in %s",fXmlFile.Data());
297     return;
298   }
299   
300   XMLNodePointer_t xcollection = xml.GetChild(xalien);
301   if (!xcollection) {
302     Error("ParseXML","cannot find the <collection> tag in %s",fXmlFile.Data());
303     return;
304   }
305   
306   XMLNodePointer_t xevent = xml.GetChild(xcollection);;
307   if (!xevent) {
308     Error("ParseXML","cannot find the <event> tag in %s",fXmlFile.Data());
309     return;
310   }
311   if (!xevent) return;
312   
313   do {
314     if (xml.GetAttr(xevent, "name")) {
315       TMap *files = new TMap();
316             
317       // files
318       XMLNodePointer_t xfile = xml.GetChild(xevent);
319       if (!xfile) continue;
320       
321       Bool_t firstfile=kTRUE;
322       do {
323         // here we have an event file
324         // get the attributes;
325         xml.GetAttr(xfile, "lfn");
326         xml.GetAttr(xfile, "turl");
327         
328         TMap *attributes = new TMap();
329         TObjString *oname = new TObjString(xml.GetAttr(xfile,"name"));
330         TObjString *oturl = new TObjString(xml.GetAttr(xfile,"turl"));
331         TObjString *olfn  = new TObjString(xml.GetAttr(xfile,"lfn"));
332         TObjString *oguid = new TObjString(xml.GetAttr(xfile,"guid"));
333         TObjString *oevlist = new TObjString(xml.GetAttr(xfile, "evlist"));
334         printf("Collection: %s - The Eventlist is %s\n",fXmlFile.Data(),oevlist->GetName());
335         if (oevlist->GetName() != "") {
336           TEntryList *xmlevlist = new TEntryList(oturl->GetName(), oguid->GetName());
337           TString stringevlist = oevlist->GetName();
338           TObjArray *evlist = stringevlist.Tokenize(",");
339           for (Int_t n = 0; n < evlist->GetEntries(); n++)  xmlevlist->Enter(atol(((TObjString *) evlist->At(n))->GetName()));
340           attributes->Add(new TObjString("evlist"), xmlevlist);
341         }
342         
343         attributes->Add(new TObjString("name"),oname);
344         attributes->Add(new TObjString("turl"),oturl);
345         attributes->Add(new TObjString("lfn"),olfn);
346         attributes->Add(new TObjString("guid"),oguid);
347         files->Add(new TObjString(xml.GetAttr(xfile,"name")) , attributes);
348         
349         // we add the first file always as a file without name to the map
350         if (firstfile) {
351           files->Add(new TObjString(""),attributes);
352           firstfile=kFALSE;
353         }
354       } while ((xfile = xml.GetNext(xfile)));
355       fEventList->Add(files);
356     }
357   } while ((xevent =  xml.GetNext(xevent)));
358 }
359