Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Dependency.h

Go to the documentation of this file.
00001 //                            Package   : omniIFR
00002 //  Dependency.h              Created   : 2004/02/22
00003 //                            Author    : Alex Tingle
00004 //
00005 //    Copyright (C) 2004 Alex Tingle.
00006 //
00007 //    This file is part of the omniIFR application.
00008 //
00009 //    omniIFR is free software; you can redistribute it and/or
00010 //    modify it under the terms of the GNU Lesser General Public
00011 //    License as published by the Free Software Foundation; either
00012 //    version 2.1 of the License, or (at your option) any later version.
00013 //
00014 //    omniIFR is distributed in the hope that it will be useful,
00015 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 //    Lesser General Public License for more details.
00018 //
00019 //    You should have received a copy of the GNU Lesser General Public
00020 //    License along with this library; if not, write to the Free Software
00021 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 #ifndef OMNIIFR__DEPENDENCY_H
00024 #define OMNIIFR__DEPENDENCY_H
00025 
00026 #include "Repository.h"
00027 #include "IdentifierUtil.h"
00028 #include <string.h> // strcasecmp
00029 
00030 namespace Omniifr {
00031 
00038 inline IRObject_impl* referenceToServant(Object_ptr obj)
00039 {
00040   IRObject_impl*          result  =NULL;
00041   PortableServer::Servant servant =NULL;
00042 
00043   try
00044   {
00045     servant=Repository_impl::inst()._poa->reference_to_servant(obj);
00046     // servant's reference count has been incremented for us.
00047     result=dynamic_cast<IRObject_impl*>(servant);
00048   }
00049   catch(PortableServer::POA::ObjectNotActive& ex)
00050   {
00051     // _poa does not contain irobject.
00052     servant=NULL;
00053     // ?? Temporary diagnostic - help to debug reincarnation:
00054     // ?? remove this when reincarnation works.
00055     DB(1,"?? Reference to object that doesn't exist yet. ??")
00056   }
00057   catch(PortableServer::POA::WrongAdapter& ex)
00058   {
00059     cerr<<"POA has wrong adapter for reference_to_servant()."<<endl;
00060     exit(1); // Programming error - so quit.
00061   }
00062   catch(PortableServer::POA::WrongPolicy& ex)
00063   {
00064     cerr<<"POA has wrong policy for reference_to_servant()."<<endl;
00065     exit(1); // Programming error - so quit.
00066   }
00067   catch(Exception& ex)
00068   {
00069     DB(1,"Failed to get reference_to_servant"
00070       IFELSE_OMNIORB4(" ("<<ex._name()<<")",)) // but press on...
00071   }
00072 
00073   if(servant && !result)
00074      servant->_remove_ref();// Balances the implicit _add_ref in ref'_to_servant()
00075   return result;
00076 }
00077 
00078 //
00079 //
00080 //
00081 
00088 template<class T_IRObject>
00089 class Dependency1 : public DependencyBase
00090 {
00091 public:
00092   Dependency1(IRObject_impl* owner)
00093     :DependencyBase(owner),_irobject(T_IRObject::_nil()),_servant(NULL){}
00094   virtual ~Dependency1(){clear();}
00095   inline typename T_IRObject::_ptr_type in() {return _irobject.in();}
00096   inline typename T_IRObject::_ptr_type copy()
00097   {
00098     return T_IRObject::_duplicate(_irobject.in());
00099   }
00100   inline void assign(typename T_IRObject::_ptr_type irobject)
00101   {
00102     typename T_IRObject::_var_type t(irobject); // ensure that irobject ref.
00103     if(CORBA::is_nil(t.in()))                   //   is released.
00104         throw CORBA::BAD_PARAM(
00105           IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidObjectRef,43),
00106           CORBA::COMPLETED_NO
00107         );
00108     clear();
00109     set(t._retn());
00110   }
00112   inline void clear()
00113   {
00114     if(_servant)
00115     {
00116       _servant->undepend(this);
00117       _servant=NULL;
00118     }
00119     _irobject=T_IRObject::_nil();
00120   }
00121 private:
00122   typename T_IRObject::_var_type _irobject;
00123   IRObject_impl*                 _servant;
00124 
00128   inline void set(typename T_IRObject::_ptr_type irobject)
00129   {
00130     _irobject=irobject;
00131     _servant=referenceToServant(irobject); // implicit _servant->_add_ref()...
00132     if(_servant)
00133     {
00134       _servant->depend(this);
00135       _servant->_remove_ref();             // ...cancelled here
00136     }
00137   }
00138 }; // end class
00139 
00140 
00142 // Dependency2
00144 
00147 template<class T_IRObjectSeq>
00148 class Dependency2 : public DependencyBase
00149 {
00150 private:
00151   T_IRObjectSeq        _irobjectSeq;
00152   list<IRObject_impl*> _servants;
00153 public:
00154   Dependency2(IRObject_impl* owner)
00155     :DependencyBase(owner),_irobjectSeq(),_servants(){}
00156   virtual ~Dependency2(){}
00157   inline const T_IRObjectSeq& in(){return _irobjectSeq;}
00158   inline T_IRObjectSeq* copy() {return new T_IRObjectSeq(_irobjectSeq);}
00159   inline void assign(const T_IRObjectSeq& irobjectSeq)
00160   {
00161     check(irobjectSeq); // Throws BAD_PARAM if a problem is found.
00162     clear();            // Does not throw any exceptions.
00163     set(irobjectSeq);
00164   }
00166   inline void clear()
00167   {
00168     for(typename list<IRObject_impl*>::iterator i=_servants.begin();
00169         i!=_servants.end();
00170         ++i)
00171     {
00172       if(*i)
00173         (*i)->undepend(this);
00174     }
00175     _servants.clear();
00176     _irobjectSeq.length(0);
00177   }
00178 private:
00179 
00187   inline void check(const T_IRObjectSeq& irobjectSeq)
00188   {
00189     for(CORBA::ULong i(0); i<irobjectSeq.length(); i++)
00190     {
00191       if(CORBA::is_nil(irobjectSeq[i]))
00192           throw CORBA::BAD_PARAM(
00193             IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidObjectRef,43),
00194             CORBA::COMPLETED_NO
00195           );
00196     }
00197   }
00198   
00202   inline void set(const T_IRObjectSeq& irobjectSeq)
00203   {
00204     assert(_servants.empty());
00205     assert(0==_irobjectSeq.length());
00206     _irobjectSeq=irobjectSeq;
00207     for(CORBA::ULong i(0); i<irobjectSeq.length(); i++)
00208     {
00209       IRObject_impl* irobject =referenceToServant(irobjectSeq[i]); // _add_ref()
00210       if(irobject)
00211       {
00212         irobject->depend(this);
00213         irobject->_remove_ref();                                   // _rem_ref()
00214       }
00215       _servants.push_back(irobject);
00216     }
00217   }
00218 }; // Dependency2
00219 
00220 
00221 
00223 // Dependency3
00225 
00230 template<class T_xxxDescriptionSeq>
00231 class Dependency3 : public DependencyBase
00232 {
00233 private:
00234   T_xxxDescriptionSeq  _descriptionSeq;
00235   list<IRObject_impl*> _servants;
00236 public:
00237   Dependency3(IRObject_impl* owner)
00238     :DependencyBase(owner),_descriptionSeq(),_servants(){}
00239   virtual ~Dependency3(){}
00240   inline const T_xxxDescriptionSeq& in(){return _descriptionSeq;}
00241   inline T_xxxDescriptionSeq* copy()
00242   {
00243     return new T_xxxDescriptionSeq(_descriptionSeq);
00244   }
00245   inline void assign(const T_xxxDescriptionSeq& descriptionSeq)
00246   {
00247     check(descriptionSeq); // Throws BAD_PARAM if a problem is found.
00248     uncheckedAssign(descriptionSeq);
00249   }
00253   inline void uncheckedAssign(const T_xxxDescriptionSeq& descriptionSeq)
00254   {
00255     clear(); // Does not throw any exceptions.
00256     set(descriptionSeq);
00257   }
00259   inline void clear()
00260   {
00261     for(typename list<IRObject_impl*>::iterator i=_servants.begin();
00262         i!=_servants.end();
00263         ++i)
00264     {
00265       if(*i)
00266         (*i)->undepend(this);
00267     }
00268     _servants.clear();
00269     _descriptionSeq.length(0);
00270   }
00271 private:
00272 
00280   inline void check(const T_xxxDescriptionSeq& descriptionSeq)
00281   {
00282     for(CORBA::ULong i(0); i<descriptionSeq.length(); i++)
00283     {
00284       IdentifierUtil::checkInvalid(descriptionSeq[i].name);
00285       if(CORBA::is_nil(descriptionSeq[i].type_def))
00286           throw CORBA::BAD_PARAM(
00287             IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidObjectRef,43),
00288             CORBA::COMPLETED_NO
00289           );
00290       for(CORBA::ULong j(i+1); j<descriptionSeq.length(); j++)
00291       {
00292         if(0==strcasecmp(descriptionSeq[i].name,descriptionSeq[j].name))
00293             throw CORBA::BAD_PARAM(
00294               IFELSE_OMNIORB4(omni::BAD_PARAM_InvalidMemberName,17),
00295               CORBA::COMPLETED_NO
00296             );
00297       }
00298     }
00299   }
00300   
00304   inline void set(const T_xxxDescriptionSeq& descriptionSeq)
00305   {
00306     assert(_servants.empty());
00307     assert(0==_descriptionSeq.length());
00308     _descriptionSeq=descriptionSeq;
00309     for(CORBA::ULong i(0); i<descriptionSeq.length(); i++)
00310     {
00311       // referenceToServant() implicitly calls _add_ref()
00312       IRObject_impl* irobject =referenceToServant(descriptionSeq[i].type_def);
00313       if(irobject)
00314       {
00315         irobject->depend(this);
00316         // cancel the implicit _add_ref() in referenceToServant().
00317         irobject->_remove_ref();
00318       }
00319       _servants.push_back(irobject);
00320     }
00321   }
00322 }; // Dependency3
00323 
00324 } // end namespace Omniifr
00325 
00326 #endif // OMNIIFR__DEPENDENCY_H

Generated on Fri Mar 4 13:03:23 2005 for OmniIFR by  doxygen 1.4.1