Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

CandHandle.cxx

Go to the documentation of this file.
00001 
00002 // $Id: CandHandle.cxx,v 1.38 2006/07/24 17:57:59 boehm Exp $
00003 //
00004 // CandHandle.cxx
00005 //
00006 // CandHandle is the base class for specialized access handles to
00007 // CandBase derived objects.
00008 //
00009 // Each concrete CandHandle must define a DupHandle function.
00010 //
00011 // Adapted from Babar's BtaCandidate (written by Gautier Hamel de
00012 // Monchenault and Bob Jacobsen).
00013 //
00014 // Author:  G. Irwin 2/2000
00016 
00017 #include <cassert>
00018 #include <iostream>
00019 
00020 #include "TString.h"
00021 
00022 #include "Candidate/CandHandle.h"
00023 #include "CandData/CandHeader.h"
00024 #include "CandData/CandRecord.h"
00025 #include "Candidate/CandUid.h"
00026 #include "MessageService/MsgService.h"
00027 
00028 ClassImp(CandHandle)
00029 
00030 // Define static members
00031 Int_t CandHandle::fsNAlloc = 0;          // Initializes fsNAlloc to zero
00032 Bool_t CandHandle::fsSlushyEnabled = kFALSE;// kTRUE=delayed cand freeze  
00033 
00034 //______________________________________________________________________
00035 CVSID("$Id: CandHandle.cxx,v 1.38 2006/07/24 17:57:59 boehm Exp $");
00036 
00037 std::ostream& operator<<(std::ostream& os, const CandHandle& ch)
00038 { return ch.FormatToOStream(os); }
00039 
00040 //______________________________________________________________________
00041   CandHandle::CandHandle() :
00042   fCandRefer(0)
00043 , fMother(0)
00044 , fLocked(kFALSE)
00045 , fViewableNotifier(0)
00046 {
00047    fsNAlloc++;
00048 }
00049 
00050 //______________________________________________________________________
00051 CandHandle::CandHandle(const CandHandle &ch) :
00052   TObject(ch)
00053 , fCandRefer(ch.fCandRefer)
00054 , fMother(0)
00055 , fLocked(kFALSE)
00056 , fViewableNotifier(0)
00057 {
00058    fsNAlloc++;
00059 }
00060 
00061 //______________________________________________________________________
00062 CandHandle::CandHandle(CandBase *cb) :
00063   fCandRefer(cb)
00064 , fMother(0)
00065 , fLocked(kFALSE)
00066 , fViewableNotifier(0)
00067 {
00068    fsNAlloc++;
00069 }
00070 
00071 //______________________________________________________________________
00072 CandHandle::~CandHandle()
00073 {
00074    DropMotherLink();
00075    fsNAlloc--;
00076 }
00077 
00078 //______________________________________________________________________
00079 CandHandle &CandHandle::operator=(const CandHandle &ch)
00080 {
00081   if (IsLocked()) {
00082     MSG("Cand", Msg::kWarning) << endl
00083        << "Attempt to reset Candidate reference in a locked CandHandle:"
00084         << endl << "Class = " << ClassName() << "  Name = " << GetName()
00085                 << endl << "This CandHandle is owned by the I/O system."
00086                    << endl << "Please create your own CandHandle first."
00087          << endl << "Then reset the Candidate reference in the new one."
00088                                       << endl << "This attempt ignored."
00089                                                         << endl << endl;
00090     return *this;
00091   }
00092 
00093   if (this != &ch) {
00094 
00095 // Assign CandRefer
00096     if (fCandRefer != ch.GetCandRefer()) fCandRefer=ch.GetCandRefer();
00097 
00098 //gmi The following statement from original Babar code looks like a bug.
00099 //gmi Why should the mother link get zeroed if the CandBase is changed?
00100 //gmi fMother = (CandHandle *) 0;              // Mother link not copied
00101   }
00102   return *this;
00103 }
00104 
00105 //______________________________________________________________________
00106 Bool_t CandHandle::operator==(const CandHandle &ch) const
00107 {
00108 
00109 // CandHandle object == operator compares Candidate addresses.
00110 // Pointer == just compares CandHandle addresses.
00111   return (GetCandBase() == ch.GetCandBase());
00112 }
00113 
00114 //______________________________________________________________________
00115 Bool_t CandHandle::operator!=(const CandHandle &ch) const
00116 {
00117 
00118 // CandHandle object != operator compares Candidate addresses.
00119 // Pointer != just compares CandHandle addresses
00120   return !(*this == ch);
00121 }
00122 
00123 //______________________________________________________________________
00124 const CandHandle *CandHandle::AddDaughterLink(CandHandle &ch,
00125                                                            Bool_t check)
00126 {
00127 
00128 // Prevent duplication of pre-existing redundant daughter if check TRUE.
00129   if (check && FindDaughter(&ch)) {
00130     MSG("Cand", Msg::kVerbose)
00131      << "Attempt to add redundant CandHandle to daughter list: ignored."
00132      << endl;
00133     return 0;
00134   }
00135   return GetOwnedCandBase()->AddDaughterLink(ch);   // Added CandHandle*
00136 }
00137 
00138 //______________________________________________________________________
00139 const CandHandle *CandHandle::CloneInTree(const CandHandle &ch) const
00140 {
00141    if (IsCloneOf(ch)) return this;
00142    TIter iterdau = GetDaughterIterator();
00143    CandHandle *dau;
00144    while ((dau=(CandHandle *) iterdau())) {
00145      const CandHandle *chh = dau->CloneInTree(ch);
00146      if (chh != 0) return chh;
00147    }
00148    return 0;
00149 }
00150 
00151 //______________________________________________________________________
00152 void CandHandle::DropMotherLink()
00153 {
00154    if (fMother == 0) return;                        // No mother to drop
00155 
00156 // Remove mother's daughter link to this
00157    if (!IsLocal()) fMother->GetCandBase()->fDaughters.Remove(this);
00158 
00159    fMother = (CandHandle *) 0;           // Set this mother link to zero
00160 }
00161 
00162 //______________________________________________________________________
00163 CandHandle *CandHandle::DupHandle() const
00164 {
00165    return (new CandHandle(*this));
00166 }
00167 
00168 //______________________________________________________________________
00169 CandHandle *CandHandle::FindDaughter(const CandHandle *ch) const
00170 {
00171 
00172 // Finds the first daughter encountered with the same Candidate
00173 // object referenced, not the same CandHandle object.
00174 
00175    TIter chli(&GetCandBase()->fDaughters);
00176    CandHandle *chi;
00177 
00178    while ((chi = dynamic_cast<CandHandle *>(chli()))) {
00179 
00180 // CandHandle object == operator is defined to compare Candidates
00181      if (*chi == *ch) return chi;
00182 
00183    }
00184    return 0;
00185 }
00186 
00187 //______________________________________________________________________
00188 const CandHandle *CandHandle::FindDaughter(const char *classname,
00189                                            const char *objname) const
00190 {
00191 
00192 // Returns const ptr to first selected CandHandle in daughter list.
00193 // If classname is a null ptr or blank string, no class selection is
00194 // done.  If classname is provided, the qualifying object must
00195 // InheritFrom() or be a classname.  The objname is optional, but,
00196 // if filled, will further qualify the selection by requiring
00197 // agreement with the GetName() method of the selected object.
00198 
00199    TString classtr("");
00200    if (classname)
00201      classtr.Append(TString(classname).Strip(TString::kBoth));
00202    TString objstr("");
00203    if (objname)
00204      objstr.Append(TString(objname).Strip(TString::kBoth));
00205 
00206    TIter chli(&GetCandBase()->fDaughters);
00207    CandHandle *ch;
00208 
00209    while ((ch = dynamic_cast<CandHandle *>(chli()))) {
00210 
00211 // First check whether ch InheritsFrom "classname"
00212      if (classtr.IsNull() || ch->InheritsFrom(classtr)) {
00213 
00214 // Then check whether ch name equals "objname"
00215        if (objstr.IsNull() || (objstr == ch->GetName()))
00216          return ch;
00217      }
00218    }
00219    return 0;
00220 }
00221 
00222 //______________________________________________________________________
00223 const AlgConfig *CandHandle::GetAlgConfig() const
00224 {
00225    return GetCandBase()->GetAlgConfig();
00226 }
00227 
00228 //______________________________________________________________________
00229 UInt_t CandHandle::GetArchUidInt() const
00230 {
00231    return GetCandBase()->GetArchUidInt();
00232 }
00233 
00234 //______________________________________________________________________
00235 CandBase *CandHandle::GetCandBase()
00236 {
00237    return fCandRefer();
00238 }
00239 
00240 //______________________________________________________________________
00241 const CandBase *CandHandle::GetCandBase() const
00242 {
00243    return fCandRefer();
00244 }
00245 
00246 //______________________________________________________________________
00247 CandRecord *CandHandle::GetCandRecord() const
00248 {
00249    return GetCandBase()->fCandRecord;
00250 }
00251 
00252 //______________________________________________________________________
00253 const CandUid &CandHandle::GetCandUid() const
00254 {
00255    return GetCandBase()->GetCandUid();
00256 }
00257 
00258 //______________________________________________________________________
00259 const CandHandle *CandHandle::GetDaughter(Int_t ndau) const
00260 {
00261    return GetCandBase()->GetDaughter(ndau);
00262 }
00263 
00264 //______________________________________________________________________
00265 TIter CandHandle::GetDaughterIterator() const
00266 {
00267    return GetCandBase()->GetDaughterIterator();
00268 }
00269 
00270 //______________________________________________________________________
00271 const CandHandle *CandHandle::GetLocalHandle() const
00272 {
00273    return GetCandBase()->GetLocalHandle();
00274 }
00275 
00276 //______________________________________________________________________
00277 const CandHandle *CandHandle::GetMother() const
00278 {
00279    if ((fMother == 0) && (GetLocalHandle() != 0) && !IsLocal()) {
00280      return GetLocalHandle()->GetMother();
00281    }
00282    return fMother;
00283 }
00284 
00285 //______________________________________________________________________
00286 const char *CandHandle::GetName() const
00287 {
00288    return GetCandBase()->GetName();
00289 }
00290 
00291 //______________________________________________________________________
00292 Int_t CandHandle::GetNDaughters() const
00293 {
00294    return GetCandBase()->GetNDaughters();
00295 }
00296 
00297 //______________________________________________________________________
00298 Int_t CandHandle::GetNRefers() const
00299 {
00300    return GetCandRefer().GetNRefers();
00301 }
00302 
00303 //______________________________________________________________________
00304 CandBase *CandHandle::GetOwnedCandBase()
00305 {
00306    if (IsLocked()) {
00307      MSG("Cand", Msg::kSynopsis) << endl
00308          << "Attempt to modify a Candidate through a locked CandHandle:"
00309         << endl << "Class = " << ClassName() << "  Name = " << GetName()
00310                 << endl << "This CandHandle is owned by the I/O system."
00311              << endl << "Please create your own CandHandle first using:"
00312                                  << endl << "(" << ClassName() << " *) "
00313                       << "mycandhandle = lockedcandhandle->DupHandle();"
00314       << endl << "Then modify the Candidate object through the new one."
00315                        << endl << "Your modification will be made to a "
00316            << "clone of the original Candidate object." << endl << endl;
00317    }
00318 
00319 // Experimental:  fsSlushyEnabled = kTRUE clones only Candidates read-in
00320    else if (CandHandle::IsSlushyEnabled()) return fCandRefer();
00321 
00322    assert(this != GetLocalHandle());           // Cannot own LocalHandle
00323    CandBase *cb = GetCandRefer().OwnRef();  // Exclusive ref to CandBase
00324 
00325 // Set CandRecord to that of mother, if any, and if not already set.
00326    if (GetMother() &&    // This CandHandle is a daughter (has a mother)
00327       (GetMother()->GetCandRecord() != cb->fCandRecord))
00328      cb->SetCandRecord(GetMother()->GetCandRecord());
00329 
00330    return cb;                               // Exclusive ref to CandBase
00331 }
00332 
00333 //______________________________________________________________________
00334 const char *CandHandle::GetTitle() const
00335 {
00336    return GetCandBase()->GetTitle();
00337 }
00338 
00339 //______________________________________________________________________
00340 UInt_t CandHandle::GetUidInt() const
00341 {
00342    return GetCandBase()->GetUidInt();
00343 }
00344 
00345 //______________________________________________________________________
00346 const VldContext *CandHandle::GetVldContext() const
00347 {
00348    CandRecord *cr = GetCandBase()->fCandRecord;
00349    if (!cr) return 0;
00350    const CandHeader *ch = cr->GetCandHeader();
00351    return ch ? &ch->GetVldContext() : 0;
00352 }
00353 
00354 //______________________________________________________________________
00355 Bool_t CandHandle::HasOverlapWith(const CandHandle &ch) const
00356 {
00357    return GetCandBase()->HasOverlapWith(*(ch.GetCandBase()));
00358 }
00359 
00360 //______________________________________________________________________
00361 Bool_t CandHandle::IsCloneOf(const CandHandle &ch) const
00362 {
00363    return GetCandUid().IsCloneOf(ch.GetCandUid());
00364 }
00365 
00366 //______________________________________________________________________
00367 Bool_t CandHandle::IsComposite() const
00368 {
00369    return GetCandBase()->IsComposite();
00370 }
00371 
00372 //______________________________________________________________________
00373 Bool_t CandHandle::IsEqual(const TObject *rhs) const
00374 {
00375 
00376 // Overloads TObject::IsEqual method.
00377    if (TObject::IsEqual(rhs)) return true;     // Tests for same address
00378 
00379 // CandHandles refer to same CandBase address.
00380    const CandHandle *rch = dynamic_cast<const CandHandle*>(rhs);
00381    if (rch == 0) return false;
00382    if (this->GetCandBase() == rch->GetCandBase()) return true;
00383 
00384    return false;
00385 }
00386 
00387 //______________________________________________________________________
00388 Bool_t CandHandle::IsEquivalent(const TObject *rhs) const
00389 {
00390 
00391 // IsEquivalent does deep comparison for templated Test... methods
00392 
00393 // Check for equivalent CandBases.
00394    const CandHandle *rch = dynamic_cast<const CandHandle*>(rhs);
00395    if (rch == NULL) {
00396     MSG("VCand", Msg::kDebug)
00397       << "CandHandle::IsEquivalent(): Comparison object not CandHandle."
00398                  << "  rhs->ClassName() = " << rhs->ClassName() << endl;
00399     return false;
00400   }
00401    if (this->IsEqual(rhs)) return true;      // Same address or CandBase
00402    if (this->GetCandBase()->IsEquivalent(rch->GetCandBase())) {
00403      return true;
00404    }
00405 
00406    return false;
00407 }
00408 
00409 //______________________________________________________________________
00410 Bool_t CandHandle::IsLocal() const
00411 {
00412    return (this == GetLocalHandle());
00413 }
00414 
00415 //______________________________________________________________________
00416 Bool_t CandHandle::RemoveDaughter(CandHandle *ch)
00417 {
00418 
00419 // Removes the first daughter encountered with the same Candidate
00420 // object referenced, not the same CandHandle object.
00421    CandHandle *chexact = FindDaughter(ch);
00422    if (chexact) return GetOwnedCandBase()->RemoveDaughter(chexact);
00423    else return kFALSE;
00424 }
00425 
00426 //______________________________________________________________________
00427 void CandHandle::SetCandRecord(CandRecord *cr)
00428 {
00429   if (cr) {                          // Don't reset a CandRecord to zero
00430     if (cr != GetCandRecord()) {                      // Change of value
00431       if (GetCandRecord()) GetOwnedCandBase()->SetCandRecord(cr);//Reset
00432       else GetCandBase()->SetCandRecord(cr);   // Init non-zero for free
00433     }
00434   }
00435 }
00436 
00437 //______________________________________________________________________
00438 void CandHandle::SetSlushyEnabled(Bool_t tf)
00439 {
00440    if (tf == CandHandle::fsSlushyEnabled) {
00441      MSG("Cand", Msg::kSynopsis)
00442        << "CandHandle::fsSlushyEnabled unchanged from "
00443        << CandHandle::fsSlushyEnabled << endl
00444        << "by call to CandHandle::SetSlushyEnabled(" << tf << ")."
00445        << endl;
00446    }
00447    else {
00448      MSG("Cand", Msg::kSynopsis)
00449        << "CandHandle::fsSlushyEnabled changed from "
00450        << CandHandle::fsSlushyEnabled << " to " << tf
00451        << endl << "by call to CandHandle::SetSlushyEnabled(Bool_t)."
00452        << endl;
00453      CandHandle::fsSlushyEnabled = tf;
00454    }
00455 }
00456 
00457 //______________________________________________________________________
00458 void CandHandle::SetLock()
00459 {
00460    fLocked = kTRUE;
00461 }
00462 
00463 //______________________________________________________________________
00464 void CandHandle::SetMotherLink(CandHandle *ch)
00465 {
00466    assert(ch != 0);                        // Can't set null mother link
00467    assert(fMother == 0);                  // Can't already have a mother
00468    assert(!IsLocal());               // Can't set mother for LocalHandle
00469    fMother = ch;                                  // Set the mother link
00470    fMother->GetCandBase()->fDaughters.Add(this);  // Add to ma's dghters
00471 }
00472 
00473 //______________________________________________________________________
00474 void CandHandle::SetName(const char *name)
00475 {
00476    GetOwnedCandBase()->SetName(name);
00477 }
00478 
00479 //______________________________________________________________________
00480 void CandHandle::SetTitle(const char *title)
00481 {
00482    GetOwnedCandBase()->SetTitle(title);
00483 }
00484 
00485 //______________________________________________________________________
00486 void CandHandle::Trace(const char *c) const
00487 {
00488   MSG("Cand", Msg::kDebug)
00489          << "**********Begin CandHandle::Trace(\"" << c << "\")" << endl
00490                   << "Information from CandHandle's CandBase: " << endl;
00491   GetCandBase()->Trace(c);
00492 
00493   if (GetMother()) {
00494     MSG("Cand", Msg::kDebug) <<
00495       "This CandHandle is in Daughter list of CandBase whose Trace is: "
00496                                                                 << endl;
00497     GetMother()->GetCandBase()->Trace("Mother's CandBase");
00498   }
00499 
00500   else {
00501     MSG("Cand", Msg::kDebug)
00502             << "Traces of CandHandle's CandBase Daughterlist: " << endl;
00503   }
00504 
00505   if (GetNDaughters()) {
00506     MSG("Cand", Msg::kDebug)
00507             << "Traces of CandHandle's CandBase Daughterlist: " << endl;
00508     TIter iterdau = GetDaughterIterator();
00509     CandHandle *dau;
00510     while ((dau = (CandHandle *) iterdau())) {
00511       dau->Trace("Daughter CandHandles");
00512     }
00513   }
00514   MSG("Cand", Msg::kDebug)
00515           << "**********End CandHandle::Trace(\"" << c << "\")" << endl;
00516 }
00517 
00518 //______________________________________________________________________
00519 void CandHandle::Print(Option_t *option) const
00520 {
00521   FormatToOStream(cout,option);
00522 }
00523 //______________________________________________________________________
00524 std::ostream& CandHandle::FormatToOStream(std::ostream& os,
00525                                           Option_t *option) const
00526 {
00527   // Format the Candidate (and Daughters) to a ostream
00528   // if option string contains:
00529   //    n    = include name
00530   //    t    = include title
00531   //    i    = include Uid's
00532   //    v[n] = verbosity level, v0 to suppresss data values 
00533   //    d[n] = include daughters to depth of [n] (infinite if no n)
00534   //           d0 means don't print daughters
00535 
00536   GetCandBase()->FormatToOStream(os,option);
00537   return GetCandBase()->FormatDaughtersToOStream(os,option);
00538 }
00539 //______________________________________________________________________

Generated on Mon Nov 23 05:26:18 2009 for loon by  doxygen 1.3.9.1