summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h
blob: 310b693d2aa09c96b0f69c456225b6d63828e641 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
// -*- C++ -*-

//=============================================================================
/**
*  @file    Topology_Object.h
*
*  $Id$
*
*  @author Jonathan Pollack <pollack_j@ociweb.com>
*/
//=============================================================================

#ifndef TOPOLOGY_OBJECT_H
#define TOPOLOGY_OBJECT_H
#include /**/ "ace/pre.h"

#include "orbsvcs/Notify/Object.h"
#include "orbsvcs/Notify/Name_Value_Pair.h"

#include "ace/SString.h"
#include "ace/Vector_T.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

/// \namespace TAO_Notify
/// \brief A namespace to be used by all of TAO's Notification Service
/// implementation.
///
/// The initial implementation used the TAO_Notify_ prefix rather than
/// a namespace.  As part of the reliable Notification Service project
/// we started using this TAO_Notify namespace,  but there are still
/// many parts of the Notification Service that are in the global
/// namespace with a TAO_NS prefix.

// @@ Wouldn't it be better to use something like
//
// namespace TAO
// {
//   namespace Notify {}
//
// }
//
namespace TAO_Notify
{

  class Topology_Saver;
  class Topology_Parent;

  /// A vector of IDS.  Used as a path from the EventChannelFactory to a proxy.
  typedef ACE_Vector <TAO_Notify_Object::ID> IdVec;

  /// \brief Interface to be implemented by savable topology objects.
  class TAO_Notify_Serv_Export Topology_Savable
  {
   public:
    /// Destructor.
    virtual ~Topology_Savable (void);

    /// Save our state to a Topology_Saver.
    ///
    /// Use the methods of a Topology_Saver to store all information we want
    /// persisted.  This function is called by our parent, which gives us a
    /// saver to use.  In turn, we must call this function on all of our
    /// children.
    /// The implementation should look like:
    ///   bool change = this->self_changed_;
    ///   this->self_changed_ = false;
    ///   this->children_changed_ = false;
    ///   if (is_persistent ())
    ///   {
    ///     bool want_all_children = saver.begin_object(
    ///       this->id(), type, attrs, change ACE_ENV_ARG_PARAMETER);
    ///     ACE_CHECK;
    ///     for all children
    ///     {
    ///       if (want_all_children || child.is_changed())
    ///       {
    ///         child.save_persistent(saver ACE_ENV_ARG_PARAMETER);
    ///         ACE_CHECK;
    ///       }
    ///     }
    ///     for all deleted children
    ///     {
    ///       saver.delete_child(child_type, child_id);
    ///     }
    ///     saver.end_object(this->id(), type ACE_ENV_ARG_PARAMETER);
    ///   )
    virtual void save_persistent (Topology_Saver& saver ACE_ENV_ARG_DECL) = 0;

    /// Re-establish connections that we had before a shutdown.
    ///
    /// After a topology restore, this method is called so we can reconnect
    /// to any external objects with whom we were interacting.  We should
    /// call the reconnect() method on all of our children to give them
    /// the chance to do the same.
    virtual void reconnect (ACE_ENV_SINGLE_ARG_DECL_NOT_USED);

  };

  /// \brief Base class for Persistent Topology Objects.
  ///
  /// Topology objects must be derived from this class to allow themselves
  /// to be persisted.
  /// Note: virtual inheritance from TopologySavable is unnecessary,
  /// but HP ACC compiler warns if it's not there.
  class TAO_Notify_Serv_Export Topology_Object :
    public virtual TAO_Notify_Object,
    public virtual Topology_Savable
  {
  public:
    /// The constructor.
    Topology_Object ();

    /// The destructor.
    virtual ~Topology_Object ();

    /// Init this object with data from <rhs>.
    virtual void initialize (Topology_Parent* topology_parent ACE_ENV_ARG_DECL);

    /// \brief Create a child of the appropriate type and return it.
    ///
    /// Use "type" as passed in to determine what kind of child (supporting
    /// the Topology_Object interface) to create and return.  Inform it of
    /// its new ID.
    virtual Topology_Object* load_child (const ACE_CString & /*type*/,
      CORBA::Long /* id */,
      const NVPList& /* attrs */
      ACE_ENV_ARG_DECL_NOT_USED);

    /// \brief Find the id associated with topology object.
    ///
    /// A bit of a hack because id is unknown to Topology_Object
    /// the get_id returns the same thing as id -- we just need someone
    /// to find it for us.
    virtual TAO_Notify_Object::ID get_id () const;

    /// \brief Get the path of id's from the root to this object.
    void get_id_path (IdVec & id_path) const;

    /// \brief Is there an unsaved change for this object or its children?
    bool is_changed () const;

  protected:
    /// \brief Should this object be saved?
    ///
    /// This is a way for send_change() and save_persistent() to find out
    /// if this object has a persistent QoS connection property.
    /// \return true (default) if object should be saved.
    virtual bool is_persistent () const;

    /// \brief Method to report change in this object
    ///
    ///  see also Topology_Parent::child_change ()
    /// \return false if save will never happen
    bool self_change (ACE_ENV_SINGLE_ARG_DECL);

    /// \brief pointer to our topological parent
    ///
    /// \return 0 if none
    Topology_Parent * topology_parent () const;

    /// \brief Handle details of propagating change
    ///
    /// \return false if save will never happen
    bool send_change (ACE_ENV_SINGLE_ARG_DECL);

  private:
    /// \brief Send change to parent.
    ///
    /// Override this if you don't expect to have a parent
    /// (top level of tree)
    /// private virtual because this should only be called from send_change()
    /// \return false if save will never happen
    virtual bool change_to_parent (ACE_ENV_SINGLE_ARG_DECL);

  protected:
    /// true if this object changed since last save_persistent
    bool self_changed_;
    /// true of any of this object's children changed since last save_persistent
    bool children_changed_;

    /// A safely-typed copy of parent_;
    Topology_Parent * topology_parent_;
  };

  /// \brief Interface for topology objects that act as parents.
  ///
  /// Any topology object which contains other topology objects
  /// must implement this interface so that it's children can signal
  /// that they have changed.
  class TAO_Notify_Serv_Export Topology_Parent : public Topology_Object
  {
  public:
    /// Called by a child that has changed.
    /// A child calls this method to report that it has changed.
    /// \return false if save will never happen
    bool child_change (ACE_ENV_SINGLE_ARG_DECL);
  };

} // namespace TAO_Notify

TAO_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "orbsvcs/Notify/Topology_Object.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"

#endif /* TOPOLOGY_OBJECT */