00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
00031 Int_t CandHandle::fsNAlloc = 0;
00032 Bool_t CandHandle::fsSlushyEnabled = kFALSE;
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
00096 if (fCandRefer != ch.GetCandRefer()) fCandRefer=ch.GetCandRefer();
00097
00098
00099
00100
00101 }
00102 return *this;
00103 }
00104
00105
00106 Bool_t CandHandle::operator==(const CandHandle &ch) const
00107 {
00108
00109
00110
00111 return (GetCandBase() == ch.GetCandBase());
00112 }
00113
00114
00115 Bool_t CandHandle::operator!=(const CandHandle &ch) const
00116 {
00117
00118
00119
00120 return !(*this == ch);
00121 }
00122
00123
00124 const CandHandle *CandHandle::AddDaughterLink(CandHandle &ch,
00125 Bool_t check)
00126 {
00127
00128
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);
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;
00155
00156
00157 if (!IsLocal()) fMother->GetCandBase()->fDaughters.Remove(this);
00158
00159 fMother = (CandHandle *) 0;
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
00173
00174
00175 TIter chli(&GetCandBase()->fDaughters);
00176 CandHandle *chi;
00177
00178 while ((chi = dynamic_cast<CandHandle *>(chli()))) {
00179
00180
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
00193
00194
00195
00196
00197
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
00212 if (classtr.IsNull() || ch->InheritsFrom(classtr)) {
00213
00214
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
00320 else if (CandHandle::IsSlushyEnabled()) return fCandRefer();
00321
00322 assert(this != GetLocalHandle());
00323 CandBase *cb = GetCandRefer().OwnRef();
00324
00325
00326 if (GetMother() &&
00327 (GetMother()->GetCandRecord() != cb->fCandRecord))
00328 cb->SetCandRecord(GetMother()->GetCandRecord());
00329
00330 return cb;
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
00377 if (TObject::IsEqual(rhs)) return true;
00378
00379
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
00392
00393
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;
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
00420
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) {
00430 if (cr != GetCandRecord()) {
00431 if (GetCandRecord()) GetOwnedCandBase()->SetCandRecord(cr);
00432 else GetCandBase()->SetCandRecord(cr);
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);
00467 assert(fMother == 0);
00468 assert(!IsLocal());
00469 fMother = ch;
00470 fMother->GetCandBase()->fDaughters.Add(this);
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
00528
00529
00530
00531
00532
00533
00534
00535
00536 GetCandBase()->FormatToOStream(os,option);
00537 return GetCandBase()->FormatDaughtersToOStream(os,option);
00538 }
00539