00001 
00002 
00003 
00004 #include "TSchemaRuleSet.h"
00005 #include "TSchemaRule.h"
00006 #include "TObjArray.h"
00007 #include "TObjString.h"
00008 #include "TClass.h"
00009 #include "TROOT.h"
00010 #include "Riostream.h"
00011 
00012 ClassImp(TSchemaRule)
00013 
00014 using namespace ROOT;
00015 
00016 
00017 TSchemaRuleSet::TSchemaRuleSet(): fPersistentRules( 0 ), fRemainingRules( 0 ),
00018                                   fAllRules( 0 ), fVersion(-3), fCheckSum( 0 )
00019 {
00020    fPersistentRules = new TObjArray();
00021    fRemainingRules  = new TObjArray();
00022    fAllRules        = new TObjArray();
00023    fAllRules->SetOwner( kTRUE );
00024 }
00025 
00026 
00027 TSchemaRuleSet::~TSchemaRuleSet()
00028 {
00029    delete fPersistentRules;
00030    delete fRemainingRules;
00031    delete fAllRules;
00032 }
00033 
00034 
00035 void TSchemaRuleSet::ls(Option_t *) const
00036 {
00037    
00038    
00039    
00040    TROOT::IndentLevel();
00041    cout << "TSchemaRuleSet for " << fClassName << ":\n";
00042    TROOT::IncreaseDirLevel();
00043    TObject *object = 0;
00044    TIter next(fPersistentRules);
00045    while ((object = next())) {
00046       object->ls(fClassName);
00047    }
00048    TROOT::DecreaseDirLevel();   
00049 }
00050 
00051 
00052 Bool_t TSchemaRuleSet::AddRules( TSchemaRuleSet* , EConsistencyCheck  )
00053 {
00054    return kFALSE;
00055 }
00056 
00057 
00058 Bool_t TSchemaRuleSet::AddRule( TSchemaRule* rule, EConsistencyCheck checkConsistency )
00059 {
00060    
00061    
00062    
00063    
00064    
00065    
00066    
00067    
00068 
00069    
00070    
00071    
00072    if( (checkConsistency != kNoCheck) && !fClass )
00073       return kFALSE;
00074 
00075    if( !rule->IsValid() )
00076       return kFALSE;
00077 
00078    
00079    
00080    
00081    if( checkConsistency == kNoCheck ) {
00082       if( rule->GetEmbed() )
00083          fPersistentRules->Add( rule );
00084       else
00085          fRemainingRules->Add( rule );
00086       fAllRules->Add( rule );
00087       return kTRUE;
00088    }
00089 
00090    
00091    
00092    
00093    
00094    TObject* obj;
00095    
00096    
00097    if( rule->GetTarget()  && !(fClass->TestBit(TClass::kIsEmulation) && (fClass->GetStreamerInfos()==0 || fClass->GetStreamerInfos()->GetEntries()==0)) ) {
00098       TObjArrayIter titer( rule->GetTarget() );
00099       while( (obj = titer.Next()) ) {
00100          TObjString* str = (TObjString*)obj;
00101          if( !fClass->GetDataMember( str->GetString() ) && !fClass->GetBaseClass( str->GetString() ) ) {
00102             if (checkConsistency == kCheckAll) {
00103                return kFALSE;
00104             } else {
00105                
00106                delete rule;
00107                return kTRUE;
00108             }
00109          }
00110       }
00111    }
00112 
00113    
00114    
00115    
00116    const TObjArray* rules = FindRules( rule->GetSourceClass() );
00117    TObjArrayIter it( rules );
00118    TSchemaRule *r;
00119 
00120    while( (obj = it.Next()) ) {
00121       r = (TSchemaRule *) obj;
00122       if( rule->Conflicts( r ) ) {
00123          delete rules;
00124          if ( *r == *rule) {
00125             
00126             
00127             delete rule;
00128             return kTRUE;
00129          }
00130          return kFALSE;
00131       }
00132    }
00133    delete rules;
00134 
00135    
00136    
00137    
00138    if( rule->GetEmbed() )
00139       fPersistentRules->Add( rule );
00140    else
00141       fRemainingRules->Add( rule );
00142    fAllRules->Add( rule );
00143 
00144    return kTRUE;
00145 }
00146 
00147 
00148 void TSchemaRuleSet::AsString(TString &out) const
00149 {
00150    
00151    
00152    TObjArrayIter it( fAllRules );
00153    TSchemaRule *rule;
00154    while( (rule = (TSchemaRule*)it.Next()) ) {
00155       rule->AsString(out);
00156       out += "\n";
00157    }
00158 }
00159 
00160 
00161 Bool_t TSchemaRuleSet::HasRuleWithSourceClass( const TString &source ) const
00162 {
00163    
00164    
00165    TObjArrayIter it( fAllRules );
00166    TObject *obj;
00167    while( (obj = it.Next()) ) {
00168       TSchemaRule* rule = (TSchemaRule*)obj;
00169       if( rule->GetSourceClass() == source )
00170          return kTRUE;
00171    }
00172    return kFALSE;
00173 }
00174 
00175 
00176 const TObjArray* TSchemaRuleSet::FindRules( const TString &source ) const
00177 {
00178    
00179    
00180    TObject*      obj;
00181    TObjArrayIter it( fAllRules );
00182    TObjArray*    arr = new TObjArray();
00183    arr->SetOwner( kFALSE );
00184    
00185    while( (obj = it.Next()) ) {
00186       TSchemaRule* rule = (TSchemaRule*)obj;
00187       if( rule->GetSourceClass() == source )
00188          arr->Add( rule );
00189    }
00190    return arr;
00191 }
00192 
00193 
00194 const TSchemaMatch* TSchemaRuleSet::FindRules( const TString &source, Int_t version ) const
00195 {
00196    
00197    
00198 
00199    TObject*      obj;
00200    TObjArrayIter it( fAllRules );
00201    TSchemaMatch* arr = new TSchemaMatch();
00202    arr->SetOwner( kFALSE );
00203 
00204    while( (obj = it.Next()) ) {
00205       TSchemaRule* rule = (TSchemaRule*)obj;
00206       if( rule->GetSourceClass() == source && rule->TestVersion( version ) )
00207          arr->Add( rule );
00208    }
00209 
00210    if( arr->GetEntriesFast() )
00211       return arr;
00212    else {
00213       delete arr;
00214       return 0;
00215    }
00216 }
00217 
00218 
00219 const TSchemaMatch* TSchemaRuleSet::FindRules( const TString &source, UInt_t checksum ) const
00220 {
00221    
00222    
00223 
00224    TObject*      obj;
00225    TObjArrayIter it( fAllRules );
00226    TSchemaMatch* arr = new TSchemaMatch();
00227    arr->SetOwner( kFALSE );
00228 
00229    while( (obj = it.Next()) ) {
00230       TSchemaRule* rule = (TSchemaRule*)obj;
00231       if( rule->GetSourceClass() == source && rule->TestChecksum( checksum ) )
00232          arr->Add( rule );
00233    }
00234 
00235    if( arr->GetEntriesFast() )
00236       return arr;
00237    else {
00238       delete arr;
00239       return 0;
00240    }
00241 }
00242 
00243 
00244 const TSchemaMatch* TSchemaRuleSet::FindRules( const TString &source, Int_t version, UInt_t checksum ) const
00245 {
00246    
00247    
00248 
00249    TObject*      obj;
00250    TObjArrayIter it( fAllRules );
00251    TSchemaMatch* arr = new TSchemaMatch();
00252    arr->SetOwner( kFALSE );
00253 
00254    while( (obj = it.Next()) ) {
00255       TSchemaRule* rule = (TSchemaRule*)obj;
00256       if( rule->GetSourceClass() == source && ( rule->TestVersion( version ) || rule->TestChecksum( checksum ) ) )
00257          arr->Add( rule );
00258    }
00259 
00260    if( arr->GetEntriesFast() )
00261       return arr;
00262    else {
00263       delete arr;
00264       return 0;
00265    }
00266 }
00267 
00268 
00269 TClass* TSchemaRuleSet::GetClass()
00270 {
00271    return fClass;
00272 }
00273 
00274 
00275 UInt_t TSchemaRuleSet::GetClassCheckSum() const
00276 {
00277    if (fCheckSum == 0 && fClass) {
00278       const_cast<TSchemaRuleSet*>(this)->fCheckSum = fClass->GetCheckSum();
00279    }
00280    return fCheckSum;
00281 }
00282 
00283 
00284 TString TSchemaRuleSet::GetClassName() const
00285 {
00286    return fClassName;
00287 }
00288 
00289 
00290 Int_t TSchemaRuleSet::GetClassVersion() const
00291 {
00292    return fVersion;
00293 }
00294 
00295 
00296 const TObjArray* TSchemaRuleSet::GetRules() const
00297 {
00298    return fAllRules;
00299 }
00300 
00301 
00302 const TObjArray* TSchemaRuleSet::GetPersistentRules() const
00303 {
00304    return fPersistentRules;
00305 }
00306 
00307 
00308 void TSchemaRuleSet::RemoveRule( TSchemaRule* rule )
00309 {
00310    
00311    fPersistentRules->Remove( rule );
00312    fRemainingRules->Remove( rule );
00313    fAllRules->Remove( rule );
00314 }
00315 
00316 
00317 void TSchemaRuleSet::RemoveRules( TObjArray* rules )
00318 {
00319    
00320    TObject*      obj;
00321    TObjArrayIter it( rules );
00322 
00323    while( (obj = it.Next()) ) {
00324       fPersistentRules->Remove( obj );
00325       fRemainingRules->Remove( obj );
00326       fAllRules->Remove( obj );
00327    }
00328 }
00329 
00330 
00331 void TSchemaRuleSet::SetClass( TClass* cls )
00332 {
00333    fClass     = cls;
00334    fClassName = cls->GetName();
00335    fVersion   = cls->GetClassVersion();
00336 }
00337 
00338 
00339 
00340 const TSchemaRule* TSchemaMatch::GetRuleWithSource( const TString& name ) const
00341 {
00342    for( Int_t i = 0; i < GetEntries(); ++i ) {
00343       TSchemaRule* rule = (ROOT::TSchemaRule*)At(i);
00344       if( rule->HasSource( name ) ) return rule;
00345    }
00346    return 0;
00347 }
00348 
00349 
00350 const TSchemaRule* TSchemaMatch::GetRuleWithTarget( const TString& name ) const
00351 {
00352    for( Int_t i=0; i<GetEntries(); ++i) {
00353       ROOT::TSchemaRule *rule = (ROOT::TSchemaRule*)At(i);
00354       if( rule->HasTarget( name ) ) return rule;
00355    }
00356    return 0;
00357 }
00358 
00359 
00360 Bool_t TSchemaMatch::HasRuleWithSource( const TString& name, Bool_t needingAlloc ) const
00361 {
00362    
00363    
00364    
00365    
00366    
00367    for( Int_t i = 0; i < GetEntries(); ++i ) {
00368       TSchemaRule* rule = (ROOT::TSchemaRule*)At(i);
00369       if( rule->HasSource( name ) ) {
00370          if (needingAlloc) {
00371             const TObjArray *targets = rule->GetTarget();
00372             if (targets && (targets->GetEntries() > 1 || targets->GetEntries()==0) ) {
00373                return kTRUE;
00374             }
00375             if (targets && name != targets->UncheckedAt(0)->GetName() ) {
00376                return kTRUE;
00377             }
00378             
00379             
00380             if (rule->GetReadFunctionPointer() || rule->GetReadRawFunctionPointer()) {
00381                return kTRUE;
00382             }
00383          } else {
00384             return kTRUE;
00385          }
00386       }
00387    }
00388    return kFALSE;
00389 }
00390 
00391 
00392 Bool_t TSchemaMatch::HasRuleWithTarget( const TString& name, Bool_t willset ) const
00393 {
00394    
00395    
00396    
00397    
00398    for( Int_t i=0; i<GetEntries(); ++i) {
00399       ROOT::TSchemaRule *rule = (ROOT::TSchemaRule*)At(i);
00400       if( rule->HasTarget( name ) ) {
00401          if (willset) {
00402             const TObjArray *targets = rule->GetTarget();
00403             if (targets && (targets->GetEntries() > 1 || targets->GetEntries()==0) ) {
00404                return kTRUE;
00405             }
00406             const TObjArray *sources = rule->GetSource();
00407             if (sources && (sources->GetEntries() > 1 || sources->GetEntries()==0) ) {
00408                return kTRUE;
00409             }
00410             if (sources && name != sources->UncheckedAt(0)->GetName() ) {
00411                return kTRUE;
00412             }            
00413             
00414             
00415             if (rule->GetReadFunctionPointer() || rule->GetReadRawFunctionPointer()) {
00416                return kTRUE;
00417             }
00418          } else {
00419             return kTRUE;
00420          }
00421       }
00422    }
00423    return kFALSE;
00424 }
00425 
00426 
00427 void TSchemaRuleSet::Streamer(TBuffer &R__b)
00428 {
00429    
00430    
00431    if (R__b.IsReading()) {
00432       R__b.ReadClassBuffer(ROOT::TSchemaRuleSet::Class(),this);
00433       fAllRules->Clear(); 
00434       fAllRules->AddAll(fPersistentRules);
00435    } else {
00436       GetClassCheckSum();
00437       R__b.WriteClassBuffer(ROOT::TSchemaRuleSet::Class(),this);
00438    }
00439 }
00440