// @(#)root/core:$Id: TSchemaRuleSet.cxx 25450 2008-09-18 21:13:42Z pcanal $
// author: Lukasz Janyst <ljanyst@cern.ch>

#include "TSchemaRuleSet.h"
#include "TSchemaRule.h"
#include "TObjArray.h"
#include "TObjString.h"
#include "TClass.h"

ClassImp(TSchemaRule)

using namespace ROOT;

//------------------------------------------------------------------------------
TSchemaRuleSet::TSchemaRuleSet(): fPersistentRules( 0 ), fRemainingRules( 0 ),
                                  fAllRules( 0 ), fVersion(-3), fCheckSum( 0 )
{
   fPersistentRules = new TObjArray();
   fRemainingRules  = new TObjArray();
   fAllRules        = new TObjArray();
   fAllRules->SetOwner( kFALSE );
}

//------------------------------------------------------------------------------
TSchemaRuleSet::~TSchemaRuleSet()
{
   delete fPersistentRules;
   delete fRemainingRules;
   delete fAllRules;
}

//------------------------------------------------------------------------------
Bool_t TSchemaRuleSet::AddRule( TSchemaRule* rule, Bool_t checkConsistency )
{
   // The consistency check always fails if the TClass object was not set!

   //---------------------------------------------------------------------------
   // Cannot verify the consistency if the TClass object is not present
   //---------------------------------------------------------------------------
   if( checkConsistency && !fClass )
      return kFALSE;

   if( !rule->IsValid() )
      return kFALSE;

   //---------------------------------------------------------------------------
   // If we don't check the consistency then we should just add the object
   //---------------------------------------------------------------------------
   if( !checkConsistency ) {
      if( rule->GetEmbed() )
         fPersistentRules->Add( rule );
      else
         fRemainingRules->Add( rule );
      fAllRules->Add( rule );
      return kTRUE;
   }

   //---------------------------------------------------------------------------
   // Check if all of the target data members specified in the rule are
   // present int the target class
   //---------------------------------------------------------------------------
   TObject* obj;
   if( rule->GetTarget() ) {
      TObjArrayIter titer( rule->GetTarget() );
      while( (obj = titer.Next()) ) {
         TObjString* str = (TObjString*)obj;
         if( !fClass->GetDataMember( str->GetString() ) && !fClass->GetBaseClass( str->GetString() ) )
            return kFALSE;
 
      }
   }

   //---------------------------------------------------------------------------
   // Check if there is a rule conflicting with this one
   //---------------------------------------------------------------------------
   const TObjArray* rules = FindRules( rule->GetSourceClass() );
   TObjArrayIter it( rules );
   TSchemaRule *r;

   while( (obj = it.Next()) ) {
      r = (TSchemaRule *) obj;
      if( rule->Conflicts( r ) ) {
         delete rules;
         return kFALSE;
      }
   }
   delete rules;

   //---------------------------------------------------------------------------
   // No conflicts - insert the rules
   //---------------------------------------------------------------------------
   if( rule->GetEmbed() )
      fPersistentRules->Add( rule );
   else
      fRemainingRules->Add( rule );
   fAllRules->Add( rule );

   return kTRUE;
}

//------------------------------------------------------------------------------
Bool_t TSchemaRuleSet::HasRuleWithSourceClass( const TString &source ) const
{
   // Return True if we have any rule whose source class is 'source'.
   
   TObjArrayIter it( fAllRules );
   TObject *obj;
   while( (obj = it.Next()) ) {
      TSchemaRule* rule = (TSchemaRule*)obj;
      if( rule->GetSourceClass() == source )
         return kTRUE;
   }
   return kFALSE;
}

//------------------------------------------------------------------------------
const TObjArray* TSchemaRuleSet::FindRules( const TString &source ) const
{
   // User has to delete the returned array
   TObject*      obj;
   TObjArrayIter it( fAllRules );
   TObjArray*    arr = new TObjArray();
   arr->SetOwner( kFALSE );
   
   while( (obj = it.Next()) ) {
      TSchemaRule* rule = (TSchemaRule*)obj;
      if( rule->GetSourceClass() == source )
         arr->Add( rule );
   }
   return arr;
}

//------------------------------------------------------------------------------
const TSchemaMatch* TSchemaRuleSet::FindRules( const TString &source, Int_t version ) const
{
   // User has to delete the returned array

   TObject*      obj;
   TObjArrayIter it( fAllRules );
   TSchemaMatch* arr = new TSchemaMatch();
   arr->SetOwner( kFALSE );

   while( (obj = it.Next()) ) {
      TSchemaRule* rule = (TSchemaRule*)obj;
      if( rule->GetSourceClass() == source && rule->TestVersion( version ) )
         arr->Add( rule );
   }

   if( arr->GetEntriesFast() )
      return arr;
   else {
      delete arr;
      return 0;
   }
}

//------------------------------------------------------------------------------
const TSchemaMatch* TSchemaRuleSet::FindRules( const TString &source, UInt_t checksum ) const
{
   // User has to delete the returned array

   TObject*      obj;
   TObjArrayIter it( fAllRules );
   TSchemaMatch* arr = new TSchemaMatch();
   arr->SetOwner( kFALSE );

   while( (obj = it.Next()) ) {
      TSchemaRule* rule = (TSchemaRule*)obj;
      if( rule->GetSourceClass() == source && rule->TestChecksum( checksum ) )
         arr->Add( rule );
   }


   if( arr->GetEntriesFast() )
      return arr;
   else {
      delete arr;
      return 0;
   }
}

//------------------------------------------------------------------------------
TClass* TSchemaRuleSet::GetClass()
{
   return fClass;
}

//------------------------------------------------------------------------------
UInt_t TSchemaRuleSet::GetClassCheckSum() const
{
   if (fCheckSum == 0 && fClass) {
      const_cast<TSchemaRuleSet*>(this)->fCheckSum = fClass->GetCheckSum();
   }
   return fCheckSum;
}

//------------------------------------------------------------------------------
TString TSchemaRuleSet::GetClassName() const
{
   return fClassName;
}

//------------------------------------------------------------------------------
Int_t TSchemaRuleSet::GetClassVersion() const
{
   return fVersion;
}

//------------------------------------------------------------------------------
const TObjArray* TSchemaRuleSet::GetRules() const
{
   return fAllRules;
}

//------------------------------------------------------------------------------
const TObjArray* TSchemaRuleSet::GetPersistentRules() const
{
   return fPersistentRules;
}

//------------------------------------------------------------------------------
void TSchemaRuleSet::RemoveRule( TSchemaRule* rule )
{
   // Remove given rule from the set - the rule is not being deleted!
   fPersistentRules->Remove( rule );
   fRemainingRules->Remove( rule );
   fAllRules->Remove( rule );
}

//------------------------------------------------------------------------------
void TSchemaRuleSet::RemoveRules( TObjArray* rules )
{
   // remove given array of rules from the set - the rules are not being deleted!
   TObject*      obj;
   TObjArrayIter it( rules );

   while( (obj = it.Next()) ) {
      fPersistentRules->Remove( obj );
      fRemainingRules->Remove( obj );
      fAllRules->Remove( obj );
   }
}

//------------------------------------------------------------------------------
void TSchemaRuleSet::SetClass( TClass* cls )
{
   fClass     = cls;
   fClassName = cls->GetName();
   fVersion   = cls->GetClassVersion();
}


//------------------------------------------------------------------------------
const TSchemaRule* TSchemaMatch::GetRuleWithSource( const TString& name ) const
{
   for( Int_t i = 0; i < GetEntries(); ++i ) {
      TSchemaRule* rule = (ROOT::TSchemaRule*)At(i);
      if( rule->HasSource( name ) ) return rule;
   }
   return 0;
}

//------------------------------------------------------------------------------
const TSchemaRule* TSchemaMatch::GetRuleWithTarget( const TString& name ) const
{
   for( Int_t i=0; i<GetEntries(); ++i) {
      ROOT::TSchemaRule *rule = (ROOT::TSchemaRule*)At(i);
      if( rule->HasTarget( name ) ) return rule;
   }
   return 0;
}

//------------------------------------------------------------------------------
Bool_t TSchemaMatch::HasRuleWithSource( const TString& name ) const
{
   for( Int_t i = 0; i < GetEntries(); ++i ) {
      TSchemaRule* rule = (ROOT::TSchemaRule*)At(i);
      if( rule->HasSource( name ) ) return kTRUE;
   }
   return kFALSE;
}

//------------------------------------------------------------------------------
Bool_t TSchemaMatch::HasRuleWithTarget( const TString& name ) const
{
   for( Int_t i=0; i<GetEntries(); ++i) {
      ROOT::TSchemaRule *rule = (ROOT::TSchemaRule*)At(i);
      if( rule->HasTarget( name ) ) return kTRUE;
   }
   return kFALSE;
}

//______________________________________________________________________________
void TSchemaRuleSet::Streamer(TBuffer &R__b)
{
   // Stream an object of class ROOT::TSchemaRuleSet.
   
   if (R__b.IsReading()) {
      R__b.ReadClassBuffer(ROOT::TSchemaRuleSet::Class(),this);
   } else {
      GetClassCheckSum();
      R__b.WriteClassBuffer(ROOT::TSchemaRuleSet::Class(),this);
   }
}


Last change: Fri Sep 19 09:32:28 2008
Last generated: 2008-09-19 09:32

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.