//*-- Author : Valeriy Onuchin 11/09/2000 
//
//
////////////////////////////////////////////////////////////////////////////////
//
// rooRelationshipObject corresponds to Relationship_Object class. 
//
// The class Relationship_Object is a self-describing data type for 
// relationships between persistent objects. An instance of this class is 
// called a relationship object.
//
//______________________________________________________________________________
//
//          About Relationship Objects
//
// Each relationship object provides access to persistent data for a particular
// relationship, called its described relationship. The persistent data consists
// of zero or more associations for a particular persistent object, called the
// source object. Each association relates the source object to a particular 
// destination object. If the described relationship is to-one, the source 
// object can be associated with at most one destination object; if the 
// described relationship is to-many, the source object can be associated with 
// more than one destination object. A relationship object uses a relationship 
// descriptor for its described relationship to guide its access to the 
// associated persistent data. You obtain a relationship object for a 
// particular relationship of a particular source object from a class object 
// for that source object. To obtain the relationship object, you call the 
// class object's get_relationship member function, specifying the relationship 
// of interest.


#include "rooObjy.h"
#include <ooas.h>
#include <oo.h>

ClassImp(rooRelationshipObject)

////////////////////////////////////////////////////////////////////////////////
//______________________________________________________________________________
 rooRelationshipObject::rooRelationshipObject()
{
   // default ctor, internal use only

   fImp = 0;
}

//______________________________________________________________________________
 rooRelationshipObject::rooRelationshipObject(const rooRelationshipObject & rel)
{
   // Constructs a relationship object that is a copy of the specified 
   // relationship object.
   //
   // The copy constructor creates a new relationship object with the same 
   // relationship descriptor and persistent relationship data as the specified
   // relationship object. Both copies access the same persistent data. Any 
   // change to associations made with one relationship object will be seen by 
   // the other relationship object.

   fImp = new Relationship_Object(*((Relationship_Object*)rel.getImp()));
}

//______________________________________________________________________________
rooRelationshipObject &rooRelationshipObject::operator=(const rooRelationshipObject & rel)
{
   // Assignment operator; sets this relationship object to a copy of the specified
   // relationship object

   *((Relationship_Object*)fImp) = *((Relationship_Object*)rel.getImp());
   return *this;
}

//______________________________________________________________________________
 rooRelationshipObject::~rooRelationshipObject()
{
   //
   
   fImp = 0;
}

//______________________________________________________________________________
 rooClassObject rooRelationshipObject::get_class_obj()
{
   // Gets a class object for the destination object that is related to the 
   // source object by the described to-one relationship.
   //
   // Returns 
   //    A class object containing data for the destination object, or a null 
   //    class object if the source object is not associated with any 
   //    destination object.
   //
   // To obtain a reference to the destination object without opening a handle 
   // to it, call get_ooref() instead of this member function.
   //
   // This member function throws exceptions:
   //    GetAssocError if it is unable to get the destination object
   //
   //    DynRelAccessError if the described relationship is to-many

   Class_Object imp = ((Relationship_Object*)fImp)->get_class_obj();
      
   if(!fClassObj) fClassObj = new rooClassObject(&imp);
   else fClassObj->setImp((void*)&imp);
   return *fClassObj; 
}

//______________________________________________________________________________
 rooObj rooRelationshipObject::get_ooref()
{
   // Gets an object reference for the destination object that is related to 
   // the source object by the described to-one relationship.
   //
   // Returns: 
   //    An object reference for the destination object, or a null object 
   //    reference if the source object is not associated with any destination 
   //    object.
   //
   // To open a handle for the destination object and obtain a class object 
   // for it, call get_class_obj() instead of this member function.
   //
   // This member function throws exceptions:
   //
   //    GetAssocError if it is unable to get the destination object
   //    DynRelAccessError if the described relationship is to-many 

   ooRef(ooObj) ref = ((Relationship_Object*)fImp)->get_ooref();
   ooHandle(ooObj) obj = ref;
   
   if(!fObject) fObject = new rooObj((void*)&obj);
   else fObject->setImp((void*)&obj);
   return *fObject;
}

//______________________________________________________________________________
 Bool_t rooRelationshipObject::get_iterator(rooObjItr & ritr, Int_t mode)
{
   // Gets an object iterator that finds all destination objects that are 
   // associated to the source object by the described to-many relationship.
   //
   // Parameters: 
   //    ritr - an Objectivity/C++ object iterator to be initialized to find 
   //          the associated destination objects.
   //    mode - intended level of access to each destination object found by 
   //          the object iterator's next member function:
   //
   //          kooNoOpen - (the default) causes next to set the object iterator 
   //                   to the next associated object without opening it.
   //
   //          kooRead - causes next to open the next associated object for read.
   //
   //          kooUpdate - causes next to open the next associated object for 
   //                   update.
   //
   // Returns: kTRUE if successful; otherwise kFALSE. 
   //
   // On the successful completion of this member function, ritr is initialized
   // to find the destination objects. That object iterator finds persistent 
   // objects, not class objects. You can construct a class object from any of 
   // these persistent objects if you want to examine its persistent data.
   //
   // This member function throws a DynRelAccessError exception if the 
   // described relationship is to-one.
   
   ooItr(ooObj)* itr = (ooItr(ooObj)*)ritr.getImp();
   return fImp ? ((Relationship_Object*)fImp)->get_iterator(*itr,(ooMode)mode) : 0;
}

//______________________________________________________________________________
 Bool_t rooRelationshipObject::exist(const rooObj & robj) const
{
   // Tests  whether an association exists to the specified destination object.

   ooHandle(ooObj)* obj = (ooHandle(ooObj)*)robj.getImp();
   return fImp ? ((Relationship_Object*)fImp)->exist(*obj) : 0;
}

//______________________________________________________________________________
 Bool_t rooRelationshipObject::exist() const
{
   // Tests whether any association exists between the source object and a
   // destination

   return fImp ? ((Relationship_Object*)fImp)->exist() : 0;
}

//______________________________________________________________________________
 void rooRelationshipObject::set(const rooObj & robj)
{
   // Forms an association between the source object and the specified 
   // destination object.
   //
   // Parameters:
   //    robj - handle for the new destination object of the described to-one 
   //          relationship.
   //
   // The application must be able to obtain an update lock for the source 
   // object. If the described relationship is bidirectional, this member 
   // function also forms the inverse association from the specified destination
   // object to the source object. In that case, the application must be able 
   // to obtain update locks on both objects. Because this member function 
   // forms to-one associations, it throws an exception if the source object 
   // is already associated with a destination object by the described
   // relationship. If you want to replace the existing destination object, 
   // you should first call del and then call this member function.
   //
   // This member function throws exceptions:
   //    SetAssocError if it is unable to form the specified association
   //    DynRelAccessError if the described relationship is to-many

   ooHandle(ooObj)* obj = (ooHandle(ooObj)*)robj.getImp();
   if(fImp) ((Relationship_Object*)fImp)->set(*obj);
}

//______________________________________________________________________________
 void rooRelationshipObject::del()
{
   // Removes all existing associations between the source object and any 
   // destination objects.
   //
   // The application must be able to obtain an update lock for the source 
   // object. If the described relationship is bidirectional, this member 
   // function also removes the inverse association to this object from each 
   // of its formerly associated destination objects. In that case, the 
   // application must be able to obtain update locks on all of the destination
   // objects. If this member function is unable to remove the association(s), 
   // it throws a DelAssocError exception.

   if(fImp) ((Relationship_Object*)fImp)->del();
}

//______________________________________________________________________________
 void rooRelationshipObject::add(const rooObj & robj)
{
   // Adds an association between the source object and the specified 
   // destination object.
   //
   // The application must be able to obtain an update lock for the source 
   // object. If the described relationship is bidirectional, this member 
   // function also adds the inverse association from the specified object to
   // the source object. In that case, the application must be able to obtain 
   // update locks on both objects. No error is signaled if an association 
   // already exists between the source object and the specified destination 
   // object. That is, you can create duplicate associations between the two 
   //objects (even though it could be semantically meaningless to do so).
   //
   // This member function throws exceptions:
   //
   //    AddAssocError if it is unable to add the specified association
   //
   //    DynRelAccessError if the described relationship is to-one
   
   ooHandle(ooObj)* obj = (ooHandle(ooObj)*)robj.getImp();
   if(fImp) ((Relationship_Object*)fImp)->add(*obj);
}

//______________________________________________________________________________
 void rooRelationshipObject::sub(const rooObj &robj, const UInt_t num)
{
   // Removes the association(s) between the source object and the specified
   // destination object.
   // 
   // Parameters: 
   //    robj - handle for the destination object whose association is to be 
   //          removed. 
   //    num -  number of associations to removed between the source object and
   //          the specified destination object:
   //       If you specify 0, all such associations are removed.
   //       If you specify 1 (the default), the first or only such association 
   //                   is removed.
   //       If you specify a number greater than 1, this member function removes
   //                   the  first number associations encountered.
   // You can use this parameter only if the described relationship is a
   // many-to-many bidirectional association or a one-to-many unidirectional
   // association.
   //
   // The application must be able to obtain an update lock for the source 
   // object. If the described relationship is bidirectional, this member 
   // function also removes the inverse association(s) from the specified 
   // destination object to the source object. In that case, the application 
   // must be able to obtain update locks on both objects.
   //
   // This member function throws exceptions:
   //    SubAssocError if it is unable to remove the specified association(s)
   //    DynRelAccessError if the described relationship is to-one
   //
   // See also: add(), get_iterator(), del()

   ooHandle(ooObj)* obj = (ooHandle(ooObj)*)robj.getImp();
   if(fImp) ((Relationship_Object*)fImp)->sub(*obj,num);
}

//______________________________________________________________________________
rooRelationship & rooRelationshipObject::relationship()
{
   // Returns a relationship descriptor for the described relationship.

   if(!fImp) return 0;
   d_Relationship& rel = ((Relationship_Object*)fImp)->relationship();
   if(!rel) return 0;
   
   if(!fRel) fRel = new rooRelationship((void*)&rel);
   else fRel->setImp((void*)&rel);
   return *fRel;    
}

//______________________________________________________________________________
const rooClass & rooRelationshipObject::other_class()
{
   // Returns a class descriptor for the destination class of the described 
   // relationship.

   return this->relationship().other_class();
}

//______________________________________________________________________________
rooClassObject &  rooRelationshipObject::contained_in()
{
   //Gets this relationship object's containing class object.
   //
   // Returns: 
   //    The class object for the persistent object whose data this 
   //    relationship object  accesses.
   //
   // The returned class object provides access to the source object for this 
   // relationship object. 
   
   if(!fImp) return 0;

   Relationship_Object* imp = (Relationship_Object*)fImp;
   Class_Object& obj = imp->contained_in();
   if(!obj) return 0;

   if(!fClassObj) fClassObj = new rooClassObject((void*)&obj);
   else fClassObj->setImp((void*)&obj);
   return *fClassObj;
}

//______________________________________________________________________________
 Bool_t rooRelationshipObject::is_relationship_object() const
{
   // Overrides the inherited member function. Indicates that this is a 
   // relationship object.

   return fImp ? ((Relationship_Object*)fImp)->is_relationship_object() : 0;
}


ROOT page - Class index - Top of the page

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.