// @(#)root/net:$Id$
// Author: A. Peters, G. Ganis   7/2/2007

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TFileStager                                                          //
//                                                                      //
// Abstract base class defining an interface to a stager.               //
//                                                                      //
// To open a connection to a stager use the static method               //
// Open("<stager>"), where <stager> contains a keyword allowing to load //
// the relevant plug-in, e.g.                                           //
//           TFileStager::Open("root://lxb6064.cern.ch")                //
// will load TXNetFileStager and initialize it for the redirector at    //
// lxb6046.cern.ch .                                                    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TError.h"
#include "TFileInfo.h"
#include "TSeqCollection.h"
#include "TFile.h"
#include "TFileStager.h"
#include "TObjString.h"
#include "TPluginManager.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TUrl.h"
#include "TCollection.h"
#include "TFileCollection.h"
#include "THashList.h"

//_____________________________________________________________________________
TList* TFileStager::GetStaged(TCollection *pathlist)
{
   // Retrieves the staging (online) status for a list of path names. Path names
   // must be of type TUrl, TFileInfo or TObjString. The returned list is the list
   // of staged files as TObjString (we use TObjString, because you can do a FindObject
   // on that list using the file name, which is not possible with TUrl objects.

   if (!pathlist) {
      Error("GetStaged", "list of pathnames was not specified!");
      return 0;
   }

   TList* stagedlist = new TList();
   TIter nxt(pathlist);
   TObject* o = 0;
   Bool_t local = (!strcmp(GetName(), "local")) ? kTRUE : kFALSE;
   while ((o = nxt())) {
      TString pn = TFileStager::GetPathName(o);
      if (pn == "") {
         Warning("GetStaged", "object is of unexpected type %s - ignoring", o->ClassName());
      } else if (local || IsStaged(pn))
         stagedlist->Add(new TObjString(pn));
   }

   // List of online files
   stagedlist->SetOwner(kTRUE);
   Info("GetStaged", "%d files staged", stagedlist->GetSize());
   return stagedlist;
}

//_____________________________________________________________________________
Bool_t TFileStager::Stage(TCollection *pathlist, Option_t *opt)
{
   // Issue a stage request for a list of files.
   // Return the '&' of all single Prepare commands.

   TIter nxt(pathlist);
   TObject *o = 0;
   Bool_t success = kFALSE;

   while ((o = nxt()))  {
      TString pn = TFileStager::GetPathName(o);
      if (pn == "") {
         Warning("Stage", "found object of unexpected type %s - ignoring",
                              o->ClassName());
         continue;
      }

      // Issue to prepare
      success &= Stage(pn, opt);
   }

   // return global flag
   return success;
}

//______________________________________________________________________________
TFileStager *TFileStager::Open(const char *stager)
{
   // Open a stager, after having loaded the relevant plug-in.
   // The format of 'stager' depends on the plug-in.

   TPluginHandler *h;
   TFileStager *s = 0;

   if (!stager) {
      ::Error("TFileStager::Open", "stager name missing: do nothing");
      return 0;
   }

   if (!gSystem->IsPathLocal(stager) &&
      (h = gROOT->GetPluginManager()->FindHandler("TFileStager", stager))) {
      if (h->LoadPlugin() == -1)
         return 0;
      s = (TFileStager *) h->ExecPlugin(1, stager);
   } else
      s = new TFileStager("local");

   return s;
}

//______________________________________________________________________________
Bool_t TFileStager::IsStaged(const char *f)
{
   // Just check if the file exists locally

   // The safest is to open in raw mode
   TUrl u(f);
   u.SetOptions("filetype=raw");
   TFile *ff = TFile::Open(u.GetUrl());
   Bool_t rc = kTRUE;
   if (!ff || ff->IsZombie()) {
      rc = kFALSE;
   }
   if (ff) {
      ff->Close();
      delete ff;
   }
   // Done
   return rc;
}

//______________________________________________________________________________
Int_t TFileStager::Locate(const char *u, TString &f)
{
   // Just check if the file exists locally

   if (!IsStaged(u))
      return -1;
   f = u;
   return 0;
}

//______________________________________________________________________________
Int_t TFileStager::LocateCollection(TFileCollection *fc, Bool_t)
{
   // Massive location of files. Returns < 0 on error, or number of files
   // processed. Results are returned on the TFileCollection itself

    TFileInfo *fi;
    TString endp;
    TIter it(fc->GetList());
    Int_t count = 0;

    while ((fi = dynamic_cast<TFileInfo *>(it.Next()))) {
       const char *ourl = fi->GetCurrentUrl()->GetUrl();
       if (!ourl) continue;

       if (Locate(ourl, endp) == 0) {
          fi->AddUrl(endp.Data(), kTRUE);
          fi->SetBit(TFileInfo::kStaged);
          fi->ResetUrl();
       }
       else {
          fi->ResetBit(TFileInfo::kStaged);
       }

       count++;
    }

   return count;
}

//_____________________________________________________________________________
TString TFileStager::GetPathName(TObject *o)
{
   // Return the path name contained in object 'o' allowing for
   // TUrl, TObjString or TFileInfo

   TString pathname;
   TString cn(o->ClassName());
   if (cn == "TUrl") {
      pathname = ((TUrl*)o)->GetUrl();
   } else if (cn == "TObjString") {
      pathname = ((TObjString*)o)->GetName();
   } else if (cn == "TFileInfo") {
      TFileInfo *fi = (TFileInfo *)o;
      pathname = (fi->GetCurrentUrl()) ? fi->GetCurrentUrl()->GetUrl() : "";
      if (fi->GetCurrentUrl()) {
         if (strlen(fi->GetCurrentUrl()->GetAnchor()) > 0) {
            TUrl url(*(fi->GetCurrentUrl()));
            url.SetAnchor("");
            pathname = url.GetUrl();
         }
      } else {
         pathname = fi->GetCurrentUrl()->GetUrl();
      }
   }

   // Done
   return pathname;
}
 TFileStager.cxx:1
 TFileStager.cxx:2
 TFileStager.cxx:3
 TFileStager.cxx:4
 TFileStager.cxx:5
 TFileStager.cxx:6
 TFileStager.cxx:7
 TFileStager.cxx:8
 TFileStager.cxx:9
 TFileStager.cxx:10
 TFileStager.cxx:11
 TFileStager.cxx:12
 TFileStager.cxx:13
 TFileStager.cxx:14
 TFileStager.cxx:15
 TFileStager.cxx:16
 TFileStager.cxx:17
 TFileStager.cxx:18
 TFileStager.cxx:19
 TFileStager.cxx:20
 TFileStager.cxx:21
 TFileStager.cxx:22
 TFileStager.cxx:23
 TFileStager.cxx:24
 TFileStager.cxx:25
 TFileStager.cxx:26
 TFileStager.cxx:27
 TFileStager.cxx:28
 TFileStager.cxx:29
 TFileStager.cxx:30
 TFileStager.cxx:31
 TFileStager.cxx:32
 TFileStager.cxx:33
 TFileStager.cxx:34
 TFileStager.cxx:35
 TFileStager.cxx:36
 TFileStager.cxx:37
 TFileStager.cxx:38
 TFileStager.cxx:39
 TFileStager.cxx:40
 TFileStager.cxx:41
 TFileStager.cxx:42
 TFileStager.cxx:43
 TFileStager.cxx:44
 TFileStager.cxx:45
 TFileStager.cxx:46
 TFileStager.cxx:47
 TFileStager.cxx:48
 TFileStager.cxx:49
 TFileStager.cxx:50
 TFileStager.cxx:51
 TFileStager.cxx:52
 TFileStager.cxx:53
 TFileStager.cxx:54
 TFileStager.cxx:55
 TFileStager.cxx:56
 TFileStager.cxx:57
 TFileStager.cxx:58
 TFileStager.cxx:59
 TFileStager.cxx:60
 TFileStager.cxx:61
 TFileStager.cxx:62
 TFileStager.cxx:63
 TFileStager.cxx:64
 TFileStager.cxx:65
 TFileStager.cxx:66
 TFileStager.cxx:67
 TFileStager.cxx:68
 TFileStager.cxx:69
 TFileStager.cxx:70
 TFileStager.cxx:71
 TFileStager.cxx:72
 TFileStager.cxx:73
 TFileStager.cxx:74
 TFileStager.cxx:75
 TFileStager.cxx:76
 TFileStager.cxx:77
 TFileStager.cxx:78
 TFileStager.cxx:79
 TFileStager.cxx:80
 TFileStager.cxx:81
 TFileStager.cxx:82
 TFileStager.cxx:83
 TFileStager.cxx:84
 TFileStager.cxx:85
 TFileStager.cxx:86
 TFileStager.cxx:87
 TFileStager.cxx:88
 TFileStager.cxx:89
 TFileStager.cxx:90
 TFileStager.cxx:91
 TFileStager.cxx:92
 TFileStager.cxx:93
 TFileStager.cxx:94
 TFileStager.cxx:95
 TFileStager.cxx:96
 TFileStager.cxx:97
 TFileStager.cxx:98
 TFileStager.cxx:99
 TFileStager.cxx:100
 TFileStager.cxx:101
 TFileStager.cxx:102
 TFileStager.cxx:103
 TFileStager.cxx:104
 TFileStager.cxx:105
 TFileStager.cxx:106
 TFileStager.cxx:107
 TFileStager.cxx:108
 TFileStager.cxx:109
 TFileStager.cxx:110
 TFileStager.cxx:111
 TFileStager.cxx:112
 TFileStager.cxx:113
 TFileStager.cxx:114
 TFileStager.cxx:115
 TFileStager.cxx:116
 TFileStager.cxx:117
 TFileStager.cxx:118
 TFileStager.cxx:119
 TFileStager.cxx:120
 TFileStager.cxx:121
 TFileStager.cxx:122
 TFileStager.cxx:123
 TFileStager.cxx:124
 TFileStager.cxx:125
 TFileStager.cxx:126
 TFileStager.cxx:127
 TFileStager.cxx:128
 TFileStager.cxx:129
 TFileStager.cxx:130
 TFileStager.cxx:131
 TFileStager.cxx:132
 TFileStager.cxx:133
 TFileStager.cxx:134
 TFileStager.cxx:135
 TFileStager.cxx:136
 TFileStager.cxx:137
 TFileStager.cxx:138
 TFileStager.cxx:139
 TFileStager.cxx:140
 TFileStager.cxx:141
 TFileStager.cxx:142
 TFileStager.cxx:143
 TFileStager.cxx:144
 TFileStager.cxx:145
 TFileStager.cxx:146
 TFileStager.cxx:147
 TFileStager.cxx:148
 TFileStager.cxx:149
 TFileStager.cxx:150
 TFileStager.cxx:151
 TFileStager.cxx:152
 TFileStager.cxx:153
 TFileStager.cxx:154
 TFileStager.cxx:155
 TFileStager.cxx:156
 TFileStager.cxx:157
 TFileStager.cxx:158
 TFileStager.cxx:159
 TFileStager.cxx:160
 TFileStager.cxx:161
 TFileStager.cxx:162
 TFileStager.cxx:163
 TFileStager.cxx:164
 TFileStager.cxx:165
 TFileStager.cxx:166
 TFileStager.cxx:167
 TFileStager.cxx:168
 TFileStager.cxx:169
 TFileStager.cxx:170
 TFileStager.cxx:171
 TFileStager.cxx:172
 TFileStager.cxx:173
 TFileStager.cxx:174
 TFileStager.cxx:175
 TFileStager.cxx:176
 TFileStager.cxx:177
 TFileStager.cxx:178
 TFileStager.cxx:179
 TFileStager.cxx:180
 TFileStager.cxx:181
 TFileStager.cxx:182
 TFileStager.cxx:183
 TFileStager.cxx:184
 TFileStager.cxx:185
 TFileStager.cxx:186
 TFileStager.cxx:187
 TFileStager.cxx:188
 TFileStager.cxx:189
 TFileStager.cxx:190
 TFileStager.cxx:191
 TFileStager.cxx:192
 TFileStager.cxx:193
 TFileStager.cxx:194
 TFileStager.cxx:195
 TFileStager.cxx:196
 TFileStager.cxx:197
 TFileStager.cxx:198
 TFileStager.cxx:199
 TFileStager.cxx:200
 TFileStager.cxx:201
 TFileStager.cxx:202
 TFileStager.cxx:203
 TFileStager.cxx:204
 TFileStager.cxx:205
 TFileStager.cxx:206
 TFileStager.cxx:207
 TFileStager.cxx:208
 TFileStager.cxx:209
 TFileStager.cxx:210
 TFileStager.cxx:211
 TFileStager.cxx:212
 TFileStager.cxx:213