CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/Fireworks/Core/src/CmsShowSearchFiles.cc

Go to the documentation of this file.
00001 #include <stdexcept>
00002 #include <iostream>
00003 #include <stdlib.h>
00004 #include <set>
00005 #include "TGClient.h"
00006 #include "TGHtml.h"
00007 #include "TGButton.h"
00008 #include "TGMenu.h"
00009 #include "TGLabel.h"
00010 #include "TGTextEntry.h"
00011 #include "TPluginManager.h"
00012 #include "TUrl.h"
00013 #include "TSocket.h"
00014 #include "TSystem.h"
00015 #include "TVirtualX.h"
00016 #include "TPRegexp.h"
00017 #include "Fireworks/Core/interface/CmsShowSearchFiles.h"
00018 #include "Fireworks/Core/interface/fwLog.h"
00019 
00020 
00021 class FWHtml : public TGHtml {
00022 public:
00023    FWHtml(const TGWindow* p, int w, int h, int id = -1):
00024    TGHtml(p,w,h,id) {}
00025    
00026    int  IsVisited(const char* iCheck) {
00027       std::string check(GetBaseUri());
00028       check +=iCheck;
00029       int value = m_visited.find(check)==m_visited.end()?kFALSE:kTRUE;
00030       return value;
00031    }
00032    void addToVisited(const char* iToVisit) {
00033       m_visited.insert(iToVisit);
00034    }
00035 private:
00036    std::set<std::string> m_visited;
00037 };
00038 
00039 static const unsigned int s_columns = 3;
00040 static const char* const s_prefixes[][s_columns] ={ 
00041   {"http://fireworks.web.cern.ch/fireworks/samples-4.2/", "Pre-selected example files","t"},
00042   {"http://uaf-2.t2.ucsd.edu/fireworks-4.2/"            , "Pre-selected example files","t"},
00043   {"http://", "Web site known by you",0},
00044   {"file:","Local file [you must type full path name]",0},
00045   {"dcap://","dCache [FNAL]",0},
00046   {"rfio://","Castor [CERN]",0}
00047   
00048 };
00049 
00050 float
00051 getURLResponseTime(const char* url)
00052 {
00053    TString com = "ping -q -c 1 -n " + TString(url) + "| tail -n 1";
00054    FILE* p = gSystem->OpenPipe(com, "r");
00055    TString l;
00056    l.Gets(p);
00057    gSystem->ClosePipe(p);
00058 
00059    TPMERegexp re("([\\d\\.]+)");
00060    if (re.Match(l))
00061       return  re[1].Atof();
00062    else
00063       return -1;
00064 }
00065 
00066 static const std::string s_httpPrefix("http:");
00067 static const std::string s_filePrefix("file:");
00068 static const std::string s_rootPostfix(".root");
00069 
00070 
00071 static const char *s_noBrowserMessage[] = {
00072    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00073    "<HTML><HEAD><TITLE>No Browser Available</TITLE> ",
00074    "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00075    "<BODY> ",
00076    //"No file browser is available for this prefix.  You can still type the full URL into the above text box to open the EDM ROOT file.<BR>",
00077    //"Only a prefix beginning in <STRONG>http:</STRONG> which contains a site name (e.g. http://www.site.org) is supported for browsing."
00078    "<b>Welcome....</b><BR>",
00079    "<BR>",
00080    "<b>You may look at examples:</b><BR>",  
00081    "If you are in Europe, open example data files at CERN:  ", " <a href=" , s_prefixes[0][0], ">",  s_prefixes[0][0], "</a><BR>",
00082    "If you are in US, open example data files at UCSD:", " <a href=" , s_prefixes[1][0], ">",  s_prefixes[1][0], "</a><BR>",
00083    "<BR>"
00084    "<b>You also may load files with Choose Prefix </b><BR>"
00085    "</BODY></HTML> ",
00086    0
00087 };
00088 
00089 static const char *s_readError[] = {
00090    "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00091    "<HTML><HEAD><TITLE>HTTP Read Error</TITLE> ",
00092    "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00093    "<BODY> ",
00094    "<P>Unknown error while trying to get file via http</P>",
00095    "</BODY></HTML> ",
00096    0
00097 };
00098 
00099 
00100 CmsShowSearchFiles::CmsShowSearchFiles (const char *filename,
00101                                         const char* windowname,
00102                                         const TGWindow* p, UInt_t w, UInt_t h)
00103    : TGTransientFrame(gClient->GetDefaultRoot(), p, w, h)
00104 {
00105    TGVerticalFrame* vf = new TGVerticalFrame(this);
00106    this->AddFrame(vf,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5));
00107    TGHorizontalFrame* urlFrame = new TGHorizontalFrame(this);
00108    vf->AddFrame(urlFrame,new TGLayoutHints(kLHintsExpandX,5,0,5,5));
00109    
00110    TGLabel* urlLabel = new TGLabel(urlFrame,"URL");
00111    urlFrame->AddFrame(urlLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,1,1,1,1));
00112    m_choosePrefix = new TGTextButton(urlFrame,"Choose Prefix");
00113    urlFrame->AddFrame(m_choosePrefix, new TGLayoutHints(kLHintsLeft,1,1,1,1));
00114    
00115    m_file= new TGTextEntry(urlFrame);
00116    urlFrame->AddFrame(m_file, new TGLayoutHints(kLHintsExpandX,1,0,1,1));
00117    m_file->Connect("TextChanged(const char*)", "CmsShowSearchFiles",this,"fileEntryChanged(const char*)");
00118    m_file->Connect("ReturnPressed()", "CmsShowSearchFiles",this,"updateBrowser()");
00119    
00120    m_webFile = new FWHtml(vf,1,1);
00121    m_webFile->Connect("MouseDown(const char*)","CmsShowSearchFiles",this,"hyperlinkClicked(const char*)");
00122    vf->AddFrame(m_webFile, new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,1,1,1,1));
00123    
00124    TGHorizontalFrame* buttonFrame = new TGHorizontalFrame(vf);
00125    vf->AddFrame(buttonFrame, new TGLayoutHints(kLHintsExpandX,1,10,1,10));
00126    
00127    m_openButton = new TGTextButton(buttonFrame,"Open");
00128    buttonFrame->AddFrame(m_openButton, new TGLayoutHints(kLHintsRight,5,5,1,1));
00129    m_openButton->SetEnabled(kFALSE);
00130    m_openButton->Connect("Clicked()","CmsShowSearchFiles",this,"openClicked()");
00131 
00132    TGTextButton* cancel = new TGTextButton(buttonFrame,"Cancel");
00133    buttonFrame->AddFrame(cancel, new TGLayoutHints(kLHintsRight,5,5,1,1));
00134    cancel->Connect("Clicked()","CmsShowSearchFiles",this,"UnmapWindow()");
00135 
00136    SetWindowName(windowname);
00137    float x1 = getURLResponseTime("lxplus.cern.ch");
00138    float x2 = getURLResponseTime("uaf-2.t2.ucsd.edu");
00139    // printf("timtes %f %f \n", x1, x2); fflush(stdout);
00140 
00141    if (x1 > 0 && x1 < x2)
00142    {
00143       sendToWebBrowser(s_prefixes[0][0]);
00144       fwLog(fwlog::kInfo) << "Search files at " << s_prefixes[0][0] << "." << std::endl;
00145    }
00146    else if ( x2 > 0)
00147    {
00148       sendToWebBrowser(s_prefixes[1][0]);
00149       fwLog(fwlog::kInfo) << "Search files at " << s_prefixes[1][0] << "." <<  std::endl;
00150    }
00151    else
00152    {
00153       sendToWebBrowser("");
00154    }
00155 
00156    MapSubwindows();
00157    Layout();
00158    m_prefixMenu=0;
00159    m_choosePrefix->Connect("Clicked()","CmsShowSearchFiles",this,"showPrefixes()");
00160 }
00161 
00162 CmsShowSearchFiles::~CmsShowSearchFiles()
00163 {
00164    delete m_prefixMenu;
00165 }
00166 
00167 void 
00168 CmsShowSearchFiles::prefixChoosen(Int_t iIndex)
00169 {
00170    m_file->SetText(m_prefixes[iIndex].c_str(),kFALSE);
00171    m_openButton->SetEnabled(kFALSE);
00172 
00173    if(m_prefixComplete[iIndex]) {
00174       //gClient->NeedRedraw(this);
00175       gClient->NeedRedraw(m_choosePrefix);
00176       gClient->NeedRedraw(m_webFile);
00177       gClient->ProcessEventsFor(this);
00178       updateBrowser();
00179    } else {
00180       sendToWebBrowser("");
00181    }
00182 }
00183 
00184 void 
00185 CmsShowSearchFiles::fileEntryChanged(const char* iFileName)
00186 {
00187    std::string fileName =iFileName;
00188    size_t index = fileName.find_last_of(".");
00189    std::string postfix;
00190    if(index != std::string::npos) {
00191       postfix=fileName.substr(index,std::string::npos);
00192    }
00193    if(postfix ==s_rootPostfix) {
00194       m_openButton->SetEnabled(kTRUE);
00195    } else {
00196       m_openButton->SetEnabled(kFALSE);
00197    }
00198 }
00199 
00200 void 
00201 CmsShowSearchFiles::updateBrowser()
00202 {
00203    sendToWebBrowser(m_file->GetText());
00204 }
00205 
00206 
00207 void 
00208 CmsShowSearchFiles::hyperlinkClicked(const char* iLink)
00209 {
00210    m_file->SetText(iLink,kTRUE);
00211    
00212    m_webFile->addToVisited(iLink);
00213    std::string fileName =iLink;
00214    size_t index = fileName.find_last_of(".");
00215    std::string postfix = fileName.substr(index,std::string::npos);
00216    
00217    if(postfix !=s_rootPostfix) {
00218       updateBrowser();
00219    } else {
00220       openClicked();
00221    }
00222 }
00223 
00224 void 
00225 CmsShowSearchFiles::openClicked()
00226 {
00227    m_openCalled=true;
00228    this->UnmapWindow();
00229 }
00230 
00231 
00232 void 
00233 CmsShowSearchFiles::showPrefixes()
00234 {
00235    if(0==m_prefixMenu) {
00236       m_prefixMenu = new TGPopupMenu(this);
00237       const char* const (*itEnd)[s_columns] = s_prefixes+sizeof(s_prefixes)/sizeof(const char*[3]);
00238       int index = 0;
00239       for(const char* const (*it)[s_columns] = s_prefixes;
00240           it != itEnd;
00241           ++it,++index) {
00242          //only add the protocols this version of the code actually can load
00243          std::string prefix = std::string((*it)[0]).substr(0,std::string((*it)[0]).find_first_of(":")+1);
00244          if(s_httpPrefix==prefix ||
00245             s_filePrefix==prefix ||
00246             (gPluginMgr->FindHandler("TSystem",prefix.c_str()) && 
00247              gPluginMgr->FindHandler("TSystem",prefix.c_str())->CheckPlugin() != -1)) {
00248                m_prefixMenu->AddEntry((std::string((*it)[0])+" ("+((*it)[1])+")").c_str(),index);
00249                m_prefixes.push_back((*it)[0]);
00250                m_prefixComplete.push_back(0!=(*it)[2]);
00251          }
00252       }
00253       m_prefixMenu->Connect("Activated(Int_t)","CmsShowSearchFiles",this,"prefixChoosen(Int_t)");
00254    }
00255    m_prefixMenu->PlaceMenu(m_choosePrefix->GetX(),m_choosePrefix->GetY(),true,true);
00256 }
00257 
00258 //Copied from TGHtmlBrowser
00259 static std::string readRemote(const char *url)
00260 {
00261    // Read (open) remote files.
00262    
00263    char *buf = 0;
00264    TUrl fUrl(url);
00265    
00266    TString msg = "GET ";
00267    msg += fUrl.GetProtocol();
00268    msg += "://";
00269    msg += fUrl.GetHost();
00270    msg += ":";
00271    msg += fUrl.GetPort();
00272    msg += "/";
00273    msg += fUrl.GetFile();
00274    msg += "\r\n";
00275    
00276    TString uri(url);
00277    if (!uri.BeginsWith("http://"))
00278       return std::string();
00279    TSocket s(fUrl.GetHost(), fUrl.GetPort());
00280    if (!s.IsValid())
00281       return std::string();
00282    if (s.SendRaw(msg.Data(), msg.Length()) == -1)
00283       return std::string();
00284    Int_t size = 1024*1024;
00285    buf = (char *)calloc(size, sizeof(char));
00286    if (s.RecvRaw(buf, size) == -1) {
00287       free(buf);
00288       return std::string();
00289    }
00290    std::string returnValue(buf);
00291    free(buf);
00292    return returnValue;
00293 }
00294 
00295 
00296 void 
00297 CmsShowSearchFiles::sendToWebBrowser(const char* iWebFile)
00298 {
00299    const std::string fileName(iWebFile);
00300    size_t index = fileName.find_first_of(":");
00301    if(index != std::string::npos) {
00302       ++index;
00303    } else {
00304       index = 0;
00305    }
00306    std::string prefix = fileName.substr(0,index);
00307 
00308    m_webFile->Clear();
00309    if(prefix == s_httpPrefix) {
00310       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kWatch));
00311       //If you clicked a hyperlink then the cursor is still a hand but we now
00312       // want it to be a watch
00313       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kWatch));
00314       //If we don't call ProcessEventsFor then the cursor will not be updated
00315       gClient->ProcessEventsFor(this);
00316       TUrl url(iWebFile);
00317       std::string buffer = readRemote(url.GetUrl());
00318       if (buffer.size()) {
00319          m_webFile->SetBaseUri(url.GetUrl());
00320          m_webFile->ParseText(const_cast<char*>(buffer.c_str()));
00321       }
00322       else {
00323          m_webFile->SetBaseUri("");
00324          for (int i=0; s_readError[i]; i++) {
00325             m_webFile->ParseText(const_cast<char *>(s_readError[i]));
00326          }
00327       }
00328       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kPointer));
00329       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kPointer));
00330    } else {
00331        m_webFile->SetBaseUri("");
00332       for (int i=0; s_noBrowserMessage[i]; i++) {
00333          m_webFile->ParseText((char *)s_noBrowserMessage[i]);
00334       }
00335    }
00336    m_webFile->Layout();
00337 }
00338 
00339 std::string 
00340 CmsShowSearchFiles::chooseFileFromURL()
00341 {
00342    DontCallClose();
00343    Connect("CloseWindow()","CmsShowSearchFiles",this,"UnmapWindow()");
00344    m_openCalled = false;
00345    MapWindow();
00346    gClient->WaitForUnmap(this);
00347 
00348    if(!m_openCalled) {
00349       return std::string();
00350    }
00351    return m_file->GetText();
00352 }
00353