00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Topology_Object.h 00006 * 00007 * Topology_Object.h,v 1.19 2006/03/14 06:14:34 jtc Exp 00008 * 00009 * @author Jonathan Pollack <pollack_j@ociweb.com> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef TOPOLOGY_OBJECT_H 00014 #define TOPOLOGY_OBJECT_H 00015 #include /**/ "ace/pre.h" 00016 00017 #include "orbsvcs/Notify/Object.h" 00018 #include "orbsvcs/Notify/Name_Value_Pair.h" 00019 00020 #include "ace/SString.h" 00021 #include "ace/Vector_T.h" 00022 00023 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00024 #pragma once 00025 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00026 00027 TAO_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 /// \namespace TAO_Notify 00030 /// \brief A namespace to be used by all of TAO's Notification Service 00031 /// implementation. 00032 /// 00033 /// The initial implementation used the TAO_Notify_ prefix rather than 00034 /// a namespace. As part of the reliable Notification Service project 00035 /// we started using this TAO_Notify namespace, but there are still 00036 /// many parts of the Notification Service that are in the global 00037 /// namespace with a TAO_NS prefix. 00038 00039 // @@ Wouldn't it be better to use something like 00040 // 00041 // namespace TAO 00042 // { 00043 // namespace Notify {} 00044 // 00045 // } 00046 // 00047 namespace TAO_Notify 00048 { 00049 class Topology_Saver; 00050 class Topology_Parent; 00051 00052 /// A vector of IDS. Used as a path from the EventChannelFactory to a proxy. 00053 typedef ACE_Vector <TAO_Notify_Object::ID> IdVec; 00054 00055 /// \brief Interface to be implemented by savable topology objects. 00056 class TAO_Notify_Serv_Export Topology_Savable 00057 { 00058 public: 00059 /// Destructor. 00060 virtual ~Topology_Savable (void); 00061 00062 /// Save our state to a Topology_Saver. 00063 /// 00064 /// Use the methods of a Topology_Saver to store all information we want 00065 /// persisted. This function is called by our parent, which gives us a 00066 /// saver to use. In turn, we must call this function on all of our 00067 /// children. 00068 /// The implementation should look like: 00069 /// bool change = this->self_changed_; 00070 /// this->self_changed_ = false; 00071 /// this->children_changed_ = false; 00072 /// if (is_persistent ()) 00073 /// { 00074 /// bool want_all_children = saver.begin_object( 00075 /// this->id(), type, attrs, change ACE_ENV_ARG_PARAMETER); 00076 /// ACE_CHECK; 00077 /// for all children 00078 /// { 00079 /// if (want_all_children || child.is_changed()) 00080 /// { 00081 /// child.save_persistent(saver ACE_ENV_ARG_PARAMETER); 00082 /// ACE_CHECK; 00083 /// } 00084 /// } 00085 /// for all deleted children 00086 /// { 00087 /// saver.delete_child(child_type, child_id); 00088 /// } 00089 /// saver.end_object(this->id(), type ACE_ENV_ARG_PARAMETER); 00090 /// ) 00091 virtual void save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL) = 0; 00092 00093 /// Re-establish connections that we had before a shutdown. 00094 /// 00095 /// After a topology restore, this method is called so we can reconnect 00096 /// to any external objects with whom we were interacting. We should 00097 /// call the reconnect() method on all of our children to give them 00098 /// the chance to do the same. 00099 virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL_NOT_USED); 00100 00101 }; 00102 00103 /// \brief Base class for Persistent Topology Objects. 00104 /// 00105 /// Topology objects must be derived from this class to allow themselves 00106 /// to be persisted. 00107 /// Note: virtual inheritance from TopologySavable is unnecessary, 00108 /// but HP ACC compiler warns if it's not there. 00109 class TAO_Notify_Serv_Export Topology_Object : 00110 public virtual TAO_Notify_Object, 00111 public virtual Topology_Savable 00112 { 00113 public: 00114 /// The constructor. 00115 Topology_Object (); 00116 00117 /// The destructor. 00118 virtual ~Topology_Object (); 00119 00120 /// Init this object with data from <rhs>. 00121 virtual void initialize (Topology_Parent* topology_parent ACE_ENV_ARG_DECL); 00122 00123 /// \brief Create a child of the appropriate type and return it. 00124 /// 00125 /// Use "type" as passed in to determine what kind of child (supporting 00126 /// the Topology_Object interface) to create and return. Inform it of 00127 /// its new ID. 00128 virtual Topology_Object* load_child (const ACE_CString & /*type*/, 00129 CORBA::Long /* id */, 00130 const NVPList& /* attrs */ 00131 ACE_ENV_ARG_DECL_NOT_USED); 00132 00133 /// \brief Find the id associated with topology object. 00134 /// 00135 /// A bit of a hack because id is unknown to Topology_Object 00136 /// the get_id returns the same thing as id -- we just need someone 00137 /// to find it for us. 00138 virtual TAO_Notify_Object::ID get_id () const; 00139 00140 /// \brief Get the path of id's from the root to this object. 00141 void get_id_path (IdVec & id_path) const; 00142 00143 /// \brief Is there an unsaved change for this object or its children? 00144 bool is_changed () const; 00145 00146 protected: 00147 /// \brief Should this object be saved? 00148 /// 00149 /// This is a way for send_change() and save_persistent() to find out 00150 /// if this object has a persistent QoS connection property. 00151 /// \return true (default) if object should be saved. 00152 virtual bool is_persistent () const; 00153 00154 /// \brief Method to report change in this object 00155 /// 00156 /// see also Topology_Parent::child_change () 00157 /// \return false if save will never happen 00158 bool self_change (ACE_ENV_SINGLE_ARG_DECL); 00159 00160 /// \brief pointer to our topological parent 00161 /// 00162 /// \return 0 if none 00163 Topology_Parent * topology_parent () const; 00164 00165 /// \brief Handle details of propagating change 00166 /// 00167 /// \return false if save will never happen 00168 bool send_change (ACE_ENV_SINGLE_ARG_DECL); 00169 00170 private: 00171 /// \brief Send change to parent. 00172 /// 00173 /// Override this if you don't expect to have a parent 00174 /// (top level of tree) 00175 /// private virtual because this should only be called from send_change() 00176 /// \return false if save will never happen 00177 virtual bool change_to_parent (ACE_ENV_SINGLE_ARG_DECL); 00178 00179 protected: 00180 /// true if this object changed since last save_persistent 00181 bool self_changed_; 00182 /// true of any of this object's children changed since last save_persistent 00183 bool children_changed_; 00184 00185 /// A safely-typed copy of parent_; 00186 Topology_Parent * topology_parent_; 00187 }; 00188 00189 /// \brief Interface for topology objects that act as parents. 00190 /// 00191 /// Any topology object which contains other topology objects 00192 /// must implement this interface so that it's children can signal 00193 /// that they have changed. 00194 class TAO_Notify_Serv_Export Topology_Parent : public Topology_Object 00195 { 00196 public: 00197 /// Called by a child that has changed. 00198 /// A child calls this method to report that it has changed. 00199 /// \return false if save will never happen 00200 bool child_change (ACE_ENV_SINGLE_ARG_DECL); 00201 }; 00202 00203 } // namespace TAO_Notify 00204 00205 TAO_END_VERSIONED_NAMESPACE_DECL 00206 00207 #if defined (__ACE_INLINE__) 00208 #include "orbsvcs/Notify/Topology_Object.inl" 00209 #endif /* __ACE_INLINE__ */ 00210 00211 #include /**/ "ace/post.h" 00212 00213 #endif /* TOPOLOGY_OBJECT */