diff options
38 files changed, 1861 insertions, 17 deletions
diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp index 0a613a94fed..1b52fced984 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.cpp @@ -80,10 +80,17 @@ TAO_Notify_CosEC_ProxyPushConsumer::connect_push_supplier (CosEventComm::PushSup this->connect (supplier ACE_ENV_ARG_PARAMETER); } -void TAO_Notify_CosEC_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) +void +TAO_Notify_CosEC_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( CORBA::SystemException )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); } + +const char * +TAO_Notify_CosEC_ProxyPushConsumer::get_proxy_type_name (void) const +{ + return "ec_proxy_push_consumer"; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h index 7cb9b02f115..85c1bfdb5ee 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushConsumer.h @@ -51,6 +51,8 @@ public: /// Release virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + protected: ///= CosNotifyChannelAdmin::ProxyPushConsumer methods diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp index e1cafd280c9..76caa3c43b5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.cpp @@ -57,3 +57,9 @@ TAO_Notify_CosEC_ProxyPushSupplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); } + +const char * +TAO_Notify_CosEC_ProxyPushSupplier::get_proxy_type_name (void) const +{ + return "ec_proxy_push_supplier"; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h index 69acbdcdacc..30aa3b97699 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/CosEC_ProxyPushSupplier.h @@ -56,6 +56,8 @@ public: /// Release virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + // = Interface methods virtual void connect_push_consumer ( CosEventComm::PushConsumer_ptr push_consumer diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp index aecb8951e81..bcfef9b3d49 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.cpp @@ -90,6 +90,8 @@ TAO_Notify_ProxyPushConsumer::connect_any_push_supplier (CosEventComm::PushSuppl ACE_CHECK; this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void TAO_Notify_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_DECL) @@ -98,4 +100,43 @@ void TAO_Notify_ProxyPushConsumer::disconnect_push_consumer (ACE_ENV_SINGLE_ARG_ )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_ProxyPushConsumer::get_proxy_type_name (void) const +{ + return "proxy_push_consumer"; +} + +void +TAO_Notify_ProxyPushConsumer::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::PushSupplier_var ps = + CosNotifyComm::PushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_any_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h index 6c732c772ad..e46b7f2434a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushConsumer.h @@ -41,6 +41,7 @@ class TAO_Notify_Serv_Export TAO_Notify_ProxyPushConsumer POA_CosNotifyChannelAdmin::ProxyPushConsumer > { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::ProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -52,6 +53,11 @@ public: /// Release virtual void release (void); +// virtual void save_persistent (TAO_NOTIFY::Topology_Saver& saver ACE_ENV_ARG_DECL); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + protected: ///= CosNotifyChannelAdmin::ProxyPushConsumer methods diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp index c5e280e9b75..0b8579fc93e 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.cpp @@ -10,6 +10,7 @@ ACE_RCSID (Notify, TAO_Notify_ProxyPushSupplier, "$Id$") #include "tao/debug.h" #include "PushConsumer.h" +#include "../Properties.h" TAO_Notify_ProxyPushSupplier::TAO_Notify_ProxyPushSupplier (void) { @@ -48,6 +49,8 @@ TAO_Notify_ProxyPushSupplier::connect_any_push_consumer (CosEventComm::PushConsu ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -57,6 +60,8 @@ TAO_Notify_ProxyPushSupplier::disconnect_push_supplier (ACE_ENV_SINGLE_ARG_DECL) )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } CosNotifyChannelAdmin::ProxyType @@ -67,3 +72,36 @@ TAO_Notify_ProxyPushSupplier::MyType (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { return CosNotifyChannelAdmin::PUSH_ANY; } + +const char * +TAO_Notify_ProxyPushSupplier::get_proxy_type_name (void) const +{ + return "proxy_push_supplier"; +} + +void +TAO_Notify_ProxyPushSupplier::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::PushConsumer_var pc = + CosNotifyComm::PushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_any_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't reconnect, tough... + } + ACE_ENDTRY; + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h index c24668ef7e8..8cd01b30e35 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/ProxyPushSupplier.h @@ -46,6 +46,7 @@ TAO_Notify_ProxySupplier_T<POA_Event_Forwarder::ProxyPushSupplier>; class TAO_Notify_Serv_Export TAO_Notify_ProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::ProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::ProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -57,6 +58,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + // = Interface methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp index d26302a2cee..f50af7e3356 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.cpp @@ -6,13 +6,14 @@ #include "PushConsumer.inl" #endif /* __ACE_INLINE__ */ -ACE_RCSID (Notify, - TAO_Notify_PushConsumer, +ACE_RCSID (Notify, + TAO_Notify_PushConsumer, "$Id$") #include "ace/Refcounted_Auto_Ptr.h" #include "orbsvcs/CosEventCommC.h" #include "../Event.h" +#include "../Properties.h" TAO_Notify_PushConsumer::TAO_Notify_PushConsumer (TAO_Notify_ProxySupplier* proxy) :TAO_Notify_Consumer (proxy) @@ -74,3 +75,23 @@ TAO_Notify_PushConsumer::push (const CosNotification::StructuredEvent& event ACE this->push_consumer_->push (any ACE_ENV_ARG_PARAMETER); } +bool +TAO_Notify_PushConsumer::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h index f5ca3aa8af9..966900dbece 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushConsumer.h @@ -55,6 +55,9 @@ public: /// Push <event> to this consumer. virtual void push (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Consumer CosEventComm::PushConsumer_var push_consumer_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp index c6d2ae4c48a..948ed38f936 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.cpp @@ -7,6 +7,7 @@ #endif /* __ACE_INLINE__ */ ACE_RCSID (Notify, TAO_Notify_PushSupplier, "$Id$") +#include "../Properties.h" TAO_Notify_PushSupplier::TAO_Notify_PushSupplier (TAO_Notify_ProxyConsumer* proxy) :TAO_Notify_Supplier (proxy) @@ -40,3 +41,23 @@ TAO_Notify_PushSupplier::release (void) delete this; //@@ inform factory } +bool +TAO_Notify_PushSupplier::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_supplier_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h index 9f9ab07131e..138913fcfd9 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Any/PushSupplier.h @@ -46,6 +46,9 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Supplier CosEventComm::PushSupplier_var push_supplier_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp index af1faff9d17..4db5521cebc 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.cpp @@ -14,6 +14,7 @@ ACE_RCSID (Notify, TAO_Notify_SequenceProxyPushConsumer, "$Id$") #include "../Method_Request_Lookup.h" #include "../Worker_Task.h" #include "../Structured/StructuredEvent.h" +#include "../Properties.h" TAO_Notify_SequenceProxyPushConsumer::TAO_Notify_SequenceProxyPushConsumer (void) :pacing_interval_ (CosNotification::PacingInterval) @@ -60,6 +61,8 @@ TAO_Notify_SequenceProxyPushConsumer::connect_sequence_push_supplier (CosNotifyC ACE_CHECK; this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -97,4 +100,43 @@ TAO_Notify_SequenceProxyPushConsumer::disconnect_sequence_push_consumer (ACE_ENV )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_SequenceProxyPushConsumer::get_proxy_type_name (void) const +{ + return "sequence_proxy_push_consumer"; +} + +void +TAO_Notify_SequenceProxyPushConsumer::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::SequencePushSupplier_var ps = + CosNotifyComm::SequencePushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_sequence_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h index b6d77b5d187..7e73ac7c7e3 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushConsumer.h @@ -40,6 +40,7 @@ class TAO_Notify_Serv_Export TAO_Notify_SequenceProxyPushConsumer : public virtual TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::SequenceProxyPushConsumer> { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::SequenceProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: /// Constuctor @@ -51,6 +52,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + protected: ///= Data Members TAO_Notify_Property_Time pacing_interval_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp index ea5501c6872..b4196fbcc83 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.cpp @@ -10,6 +10,7 @@ ACE_RCSID (Notify, TAO_Notify_SequenceProxyPushSupplier, "$Id$") #include "tao/debug.h" #include "SequencePushConsumer.h" +#include "../Properties.h" TAO_Notify_SequenceProxyPushSupplier::TAO_Notify_SequenceProxyPushSupplier (void) { @@ -47,6 +48,8 @@ TAO_Notify_SequenceProxyPushSupplier::connect_sequence_push_consumer (CosNotifyC ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -57,6 +60,8 @@ TAO_Notify_SequenceProxyPushSupplier::disconnect_sequence_push_supplier (ACE_ENV { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } CosNotifyChannelAdmin::ProxyType @@ -67,3 +72,36 @@ TAO_Notify_SequenceProxyPushSupplier::MyType (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) { return CosNotifyChannelAdmin::PUSH_SEQUENCE; } + +const char * +TAO_Notify_SequenceProxyPushSupplier::get_proxy_type_name (void) const +{ + return "sequence_proxy_push_supplier"; +} + +void +TAO_Notify_SequenceProxyPushSupplier::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::SequencePushConsumer_var pc = + CosNotifyComm::SequencePushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_sequence_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't reconnect, tough + } + ACE_ENDTRY; + } +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h index 0e34de6a20b..757d4b3e493 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequenceProxyPushSupplier.h @@ -46,6 +46,7 @@ TAO_Notify_ProxySupplier_T<POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> class TAO_Notify_Serv_Export TAO_Notify_SequenceProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_CosNotifyChannelAdmin::SequenceProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: @@ -58,6 +59,10 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + virtual const char * get_proxy_type_name (void) const; + + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + /// = Servant methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) ACE_THROW_SPEC (( diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp index 56d7a13538d..1a6268aa7d7 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.cpp @@ -17,6 +17,7 @@ ACE_RCSID (Notify, TAO_Notify_SequencePushConsumer, "$Id$") #include "../Method_Request_Event.h" #include "../Timer.h" #include "../Proxy.h" +#include "../Properties.h" TAO_Notify_SequencePushConsumer::TAO_Notify_SequencePushConsumer (TAO_Notify_ProxySupplier* proxy) : TAO_Notify_Consumer (proxy), pacing_interval_ (ACE_Time_Value::zero), timer_id_ (-1), buffering_strategy_ (0), @@ -195,3 +196,23 @@ TAO_Notify_SequencePushConsumer::push (const CosNotification::EventBatch& event_ } ACE_ENDTRY; } +bool +TAO_Notify_SequencePushConsumer::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h index 6cbe894caa3..8037ea6d403 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushConsumer.h @@ -73,6 +73,9 @@ public: /// Override, Peer::qos_changed virtual void qos_changed (const TAO_Notify_QoSProperties& qos_properties); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// When the pacing interval is used, handle_timeout () is called by /// the reactor. diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp index d7fe6a1d682..e5699464314 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.cpp @@ -8,6 +8,8 @@ ACE_RCSID (Notify, TAO_Notify_SequencePushSupplier, "$Id$") +#include "../Properties.h" + TAO_Notify_SequencePushSupplier::TAO_Notify_SequencePushSupplier (TAO_Notify_ProxyConsumer* proxy) :TAO_Notify_Supplier (proxy) { @@ -31,3 +33,23 @@ TAO_Notify_SequencePushSupplier::release (void) delete this; //@@ inform factory } +bool +TAO_Notify_SequencePushSupplier::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_supplier_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h index a74f32fe500..11ff6e5ed7f 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Sequence/SequencePushSupplier.h @@ -45,6 +45,9 @@ public: /// TAO_Notify_Destroy_Callback methods virtual void release (void); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Supplier CosNotifyComm::SequencePushSupplier_var push_supplier_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp index b29fb8f0e6b..7192f0a47b5 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.cpp @@ -59,8 +59,9 @@ TAO_Notify_StructuredProxyPushConsumer::connect_structured_push_supplier (CosNot supplier->init (push_supplier ACE_ENV_ARG_PARAMETER); ACE_CHECK; - this->connect (supplier ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -94,4 +95,43 @@ TAO_Notify_StructuredProxyPushConsumer::disconnect_structured_push_consumer (ACE )) { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); + +} +const char * +TAO_Notify_StructuredProxyPushConsumer::get_proxy_type_name (void) const +{ + return "structured_proxy_push_consumer"; +} + +void +TAO_Notify_StructuredProxyPushConsumer::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::StructuredPushSupplier_var ps = + CosNotifyComm::StructuredPushSupplier::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + // minor hack: suppress generating subscription updates during reload. + bool save_updates = this->updates_off_; + this->updates_off_ = true; + this->connect_structured_push_supplier(ps.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->updates_off_ = save_updates; + } + ACE_CATCHANY + { + // if we can't reconnect to peer, tough... + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h index 4d12ce3a297..ae5aa71f55d 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushConsumer.h @@ -40,6 +40,7 @@ class TAO_Notify_Serv_Export TAO_Notify_StructuredProxyPushConsumer : public virtual TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::StructuredProxyPushConsumer> { + typedef TAO_Notify_ProxyConsumer_T <POA_CosNotifyChannelAdmin::StructuredProxyPushConsumer> SuperClass; friend class TAO_Notify_Builder; public: @@ -52,6 +53,8 @@ public: /// Release virtual void release (void); + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + protected: // = interface methods @@ -69,14 +72,14 @@ protected: CosEventChannelAdmin::AlreadyConnected )); -virtual void push_structured_event ( - const CosNotification::StructuredEvent & notification - ACE_ENV_ARG_DECL - ) - ACE_THROW_SPEC (( - CORBA::SystemException, - CosEventComm::Disconnected - )); + virtual void push_structured_event ( + const CosNotification::StructuredEvent & notification + ACE_ENV_ARG_DECL + ) + ACE_THROW_SPEC (( + CORBA::SystemException, + CosEventComm::Disconnected + )); virtual void disconnect_structured_push_consumer ( ACE_ENV_SINGLE_ARG_DECL @@ -84,6 +87,8 @@ virtual void push_structured_event ( ACE_THROW_SPEC (( CORBA::SystemException )); + + virtual const char * get_proxy_type_name (void) const; }; #if defined(_MSC_VER) && (_MSC_VER >= 1200) diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp index 4417d59682a..553a72498f0 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.cpp @@ -1,14 +1,17 @@ // $Id$ #include "StructuredProxyPushSupplier.h" + +#if ! defined (__ACE_INLINE__) +#include "StructuredProxyPushSupplier.inl" +#endif /* __ACE_INLINE__ */ + #include "tao/PortableServer/Servant_Base.h" #include "tao/debug.h" #include "StructuredPushConsumer.h" +#include "../Properties.h" -#if ! defined (__ACE_INLINE__) -#include "StructuredProxyPushSupplier.inl" -#endif /* __ACE_INLINE__ */ ACE_RCSID(RT_Notify, TAO_Notify_StructuredProxyPushSupplier, "$Id$") @@ -57,6 +60,8 @@ TAO_Notify_StructuredProxyPushSupplier::connect_structured_push_consumer (CosNot ACE_CHECK; this->connect (consumer ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); } void @@ -67,4 +72,39 @@ TAO_Notify_StructuredProxyPushSupplier::disconnect_structured_push_supplier (ACE { this->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + this->self_change (ACE_ENV_SINGLE_ARG_PARAMETER); +} + +const char * +TAO_Notify_StructuredProxyPushSupplier::get_proxy_type_name (void) const +{ + return "structured_proxy_push_supplier"; +} + +void +TAO_Notify_StructuredProxyPushSupplier::load_attrs (const TAO_NOTIFY::NVPList& attrs) +{ + SuperClass::load_attrs(attrs); + ACE_CString ior; + if (attrs.load("PeerIOR", ior) && ior.length() > 0) + { + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::Object_var obj = orb->string_to_object(ior.c_str() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + CosNotifyComm::StructuredPushConsumer_var pc = + CosNotifyComm::StructuredPushConsumer::_unchecked_narrow(obj.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + this->connect_structured_push_consumer(pc.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + // if we can't connect... tough + } + ACE_ENDTRY; + } } diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h index b308766a4ce..771318e4b3a 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredProxyPushSupplier.h @@ -47,6 +47,7 @@ TAO_Notify_ProxySupplier_T<POA_Event_Forwarder::StructuredProxyPushSupplier>; class TAO_Notify_Serv_Export TAO_Notify_StructuredProxyPushSupplier : public virtual TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::StructuredProxyPushSupplier> { + typedef TAO_Notify_ProxySupplier_T <POA_Event_Forwarder::StructuredProxyPushSupplier> SuperClass; friend class TAO_Notify_Builder; public: @@ -59,6 +60,8 @@ public: /// Release virtual void release (void); + virtual void load_attrs (const TAO_NOTIFY::NVPList& attrs); + /// = Servant methods // = interface methods virtual CosNotifyChannelAdmin::ProxyType MyType (ACE_ENV_SINGLE_ARG_DECL) @@ -83,6 +86,7 @@ public: CORBA::SystemException )); + virtual const char * get_proxy_type_name (void) const; }; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp index 185ffe305a1..cccd6095513 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.cpp @@ -1,7 +1,5 @@ // $Id$ #include "StructuredPushConsumer.h" -#include "ace/Refcounted_Auto_Ptr.h" -#include "../Event.h" #if ! defined (__ACE_INLINE__) #include "StructuredPushConsumer.inl" @@ -9,6 +7,10 @@ ACE_RCSID(RT_Notify, TAO_Notify_StructuredPushConsumer, "$Id$") +#include "../Properties.h" +#include "../Event.h" +#include "ace/Refcounted_Auto_Ptr.h" + TAO_Notify_StructuredPushConsumer::TAO_Notify_StructuredPushConsumer (TAO_Notify_ProxySupplier* proxy) :TAO_Notify_Consumer (proxy) { @@ -61,3 +63,23 @@ TAO_Notify_StructuredPushConsumer::push (const CosNotification::StructuredEvent& { this->push_consumer_->push_structured_event (event ACE_ENV_ARG_PARAMETER); } +bool +TAO_Notify_StructuredPushConsumer::get_ior (ACE_CString & iorstr) const +{ + bool result = false; + CORBA::ORB_var orb = TAO_Notify_PROPERTIES::instance()->orb(); + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA::String_var ior = orb->object_to_string(this->push_consumer_.in() ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + iorstr = ACE_static_cast (const char *, ior.in ()); + result = true; + } + ACE_CATCHANY + { + ACE_ASSERT(0); + } + ACE_ENDTRY; + return result; +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h index 1dca5c25440..9cb0c7d1288 100644 --- a/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h +++ b/TAO/orbsvcs/orbsvcs/Notify/Structured/StructuredPushConsumer.h @@ -57,6 +57,9 @@ public: /// Push <event> to this consumer. virtual void push (const CosNotification::StructuredEvent& event ACE_ENV_ARG_DECL); + /// Retrieve the ior of this peer + virtual bool get_ior (ACE_CString & iorstr) const; + protected: /// The Consumer CosNotifyComm::StructuredPushConsumer_var push_consumer_; diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp new file mode 100644 index 00000000000..987cd738933 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.cpp @@ -0,0 +1,148 @@ +// $Id$ + +#include "Topology_Object.h" + +#if ! defined (__ACE_INLINE__) +#include "Topology_Object.inl" +#endif /* __ACE_INLINE__ */ + +// question: is there a race_conditon with self_changed and children_changed? +// answer: toplogy_changed and/or children_changed must be set after the change is +// made, and before the call to child_change. +// self_changed and children_changed must be cleared before this object and its +// children have been saved in Topology_Object::save_persistent (). +// If these rules are followed, the only risk is a (harmless) extra save. + +namespace TAO_NOTIFY +{ + void + Topology_Savable::reconnect (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) + { + } + + Topology_Object::Topology_Object () + : self_changed_ (false) + , children_changed_ (false) + , topology_parent_ (0) + { + } + + Topology_Object::~Topology_Object () + { + } + + void + Topology_Object::init (Topology_Parent * parent) + { + this->topology_parent_ = parent; + TAO_Notify_Object::init (parent); + } + + Topology_Parent * + Topology_Object::topology_parent () const + { + return this->topology_parent_; + } + + + Topology_Object * + Topology_Object::load_child (const ACE_CString & /*type*/, + CORBA::Long /* id */, + const NVPList& /* attrs */ + ACE_ENV_ARG_DECL_NOT_USED) + { + return 0; + } + + bool + Topology_Object::is_persistent () const + { + bool result = false; + if (this->qos_properties_.event_reliability().is_valid ()) + { + result = CosNotification::Persistent == this->qos_properties_.event_reliability().value (); + } + else if (this->topology_parent () != 0) + { + result = this->topology_parent ()->is_persistent (); + } + return result; + } + + bool + Topology_Object::self_change (ACE_ENV_SINGLE_ARG_DECL) + { + this->self_changed_ = true; + return send_change (ACE_ENV_SINGLE_ARG_PARAMETER); + } + + bool + Topology_Object::send_change (ACE_ENV_SINGLE_ARG_DECL) + { + bool saving = false; + if (is_persistent ()) + { + while (this->self_changed_ || this->children_changed_) + { + saving = this->change_to_parent (ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + if (!saving) + { + this->self_changed_ = false; + this->children_changed_ = false; + } + } + } + else + { + this->self_changed_ = false; + this->children_changed_ = false; + } + return saving; + } + + bool + Topology_Object::change_to_parent (ACE_ENV_SINGLE_ARG_DECL) + { + bool result = false; + Topology_Parent * parent = this->topology_parent(); + if (parent != 0) + { + result = parent->child_change(ACE_ENV_SINGLE_ARG_PARAMETER); + } + return result; + } + + void + Topology_Object::get_id_path (TAO_NOTIFY::IdVec & id_path) const + { + if (this->topology_parent() != 0) + { + this->topology_parent()->get_id_path (id_path); + } + id_path.push_back (this->get_id ()); + } + + TAO_Notify_Object_Id + Topology_Object::get_id () const + { + // If this assert triggers then implement the + // get_id method in the actual class + // derived from Topology_Object + // or else figure out why this method was called + // on an object that doesn't have an id. + ACE_ASSERT (false); + // if it is called in a release build, provide 'em a value + return -1; + } + + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Vector <TAO_Notify_Object_Id>; +template class ACE_Array_Base <TAO_Notify_Object_Id>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Vector <TAO_Notify_Object_Id> +#pragma instantiate ACE_Array_Base <TAO_Notify_Object_Id> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ + +} // namespace TAO_NOTIFY diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h new file mode 100644 index 00000000000..de7adc1c23b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.h @@ -0,0 +1,198 @@ +/* -*- 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 "Object.h" +#include "Name_Value_Pair.h" +#include "Types.h" + +#include <tao/corba.h> + +#include <ace/SString.h> +#include <ace/Vector_T.h> + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + + +/// \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. +namespace TAO_NOTIFY +{ + static const char TOPOLOGY_ID_NAME[] = "TopologyID"; + + 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: + /// 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. + class TAO_Notify_Serv_Export Topology_Object : public virtual TAO_Notify_Object, public Topology_Savable + { + public: + /// The constructor. + Topology_Object (); + + /// The destructor. + virtual ~Topology_Object (); + + /// Init this object with data from <rhs>. + /// Intentionally hides TAO_NotifyObject::init + void init (Topology_Parent * topology_parent); + + /// \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 + +#if defined (__ACE_INLINE__) +#include "Topology_Object.inl" +#endif /* __ACE_INLINE__ */ + +#include /**/ "ace/post.h" + +#endif /* TOPOLOGY_OBJECT */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl new file mode 100644 index 00000000000..1c12c7df671 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Object.inl @@ -0,0 +1,20 @@ +// $Id$ +namespace TAO_NOTIFY +{ + ACE_INLINE + bool + Topology_Object::is_changed () const + { + return this->self_changed_ | this->children_changed_; + } + + ACE_INLINE + bool + Topology_Parent::child_change (ACE_ENV_SINGLE_ARG_DECL) + { + this->children_changed_ = true; + return send_change (ACE_ENV_SINGLE_ARG_PARAMETER); + } + +} // namespace TAO_NOTIFY + diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp new file mode 100644 index 00000000000..a8aa71b1d15 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.cpp @@ -0,0 +1,13 @@ +// $Id$ + +#include "Topology_Saver.h" + +TAO_NOTIFY::Topology_Saver::~Topology_Saver () +{ +} + +void +TAO_NOTIFY::Topology_Saver::close (ACE_ENV_SINGLE_ARG_DECL_NOT_USED) +{ + +} diff --git a/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h new file mode 100644 index 00000000000..053b09519c3 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/Topology_Saver.h @@ -0,0 +1,111 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** +* @file Topology_Saver.h +* +* $Id$ +* +* @author Jonathan Pollack <pollack_j@ociweb.com> +*/ +//============================================================================= + +#ifndef TOPOLOGY_SAVER_H +#define TOPOLOGY_SAVER_H +#include /**/ "ace/pre.h" + +#include "Topology_Object.h" +#include "notify_export.h" + +#include "tao/corba.h" +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_NOTIFY +{ + /** + * \brief An interface to be implemented by objects that save Topology. + * + * A persistent topology store must provide an implemention this interface. + * + */ + class TAO_Notify_Serv_Export Topology_Saver + { + public: + + /// The destructor. + virtual ~Topology_Saver (); + + /** \brief Begin the storage of an object. + * + * Call this function with the type and ID of an object to be stored. + * This object may have children, and this will necessitate nested calls + * to begin_object. + * Design principle: + * Names should be descriptive enough to allow the objects' parent to create + * an instance of the desired class. This instance will be registered + * with the poa using the id. + * The instance itself should will load its own attributes. + * Example <proxy type="push_supplier" events="any" id="20"...> is not a + * good design because the name "proxy" is not descriptive enough. + * "<structured_proxy_push_supplier id="20"...> is better because this + * allows the parent to create the correct type of object without decoding + * attributes. + * \param id numeric id for this object + * \param type string containing the unique type name for this class of objects + * \param attrs a collection of name/value attributes + * \param change true if this object's attributes have changed. + * \return bool want_all_children. If true even changed children should be saved. + */ + virtual bool begin_object (CORBA::Long id, + const ACE_CString &type, + const NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL) = 0; + + /** \brief Report deleted children to the saver. + * + * Use the ID and "type" as passed in to determine which child we should + * delete. A parent should call this function when one of its children + * is deleted. + * \param id numeric id for the deleted child + * \param type the type name for the class of the deleted child. + * + */ + virtual void delete_child ( + CORBA::Long id, + const ACE_CString & type + ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_UNUSED_ARG (id); + ACE_UNUSED_ARG (type); + } + + /** \brief End the storage of an object. + * + * This function should be called to end the scope of the current object + * and commit it to the persistent store. + */ + virtual void end_object (CORBA::Long id, + const ACE_CString &type + ACE_ENV_ARG_DECL) = 0; + + /** + * \brief Close the saver. + * + * This is not pure virtual. The default implementation does nothing. + * + * There should be a corresponding open, but the signature may + * vary based on the type of saver, so we can't include it in the + * interface. + */ + virtual void close (ACE_ENV_SINGLE_ARG_DECL); + }; +} // namespace TAO_NOTIFY + +#include /**/ "ace/post.h" + +#endif /* TOPOLOGY_SAVER */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp new file mode 100644 index 00000000000..9985a086a73 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.cpp @@ -0,0 +1,228 @@ +// $Id$ + +#include "XML_Loader.h" +#include "Topology_Object.h" + +#include "ACEXML/common/DefaultHandler.h" +#include "ACEXML/parser/parser/Parser.h" +#include "ACEXML/common/FileCharStream.h" + +#include "ace/Containers_T.h" +#include <tao/debug.h> +#include "ace/OS_NS_unistd.h" + +//#define DEBUG_LEVEL 9 +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL TAO_debug_level +#endif + +using namespace TAO_NOTIFY; + +namespace { + CORBA::Long makeNVPList (NVPList& nvp, ACEXML_Attributes* attrs) + { + CORBA::Long id = 0; + for (size_t i = 0; i < attrs->getLength (); ++i) + { + const char * name = attrs->getQName (i); + const char * value = attrs->getValue (i); + if (ACE_OS::strcmp (name, TOPOLOGY_ID_NAME) == 0) + { + id = ACE_OS::atoi (value); + } + nvp.push_back (NVP (name, value)); + } + return id; + } +} + +namespace TAO_NOTIFY +{ + XML_Loader::XML_Loader () + : input_ (0) + , live_ (false) + { + } + + XML_Loader::~XML_Loader () + { + } + + bool + XML_Loader::open (const ACE_CString & base_name) + { + bool result = false; + + // if *.xml exists, use it + // if it does not exist then + // use the previous one was renamed to *.000 + // If neither *.xml nor *.000 exist then something + // "impossible" happened (or its a new system with no saved state). + + this->file_name_ = base_name; + this->file_name_ += ".xml"; + + // 4 is "read permission" + result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); + if (result) + { + this->live_ = false; + ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; + // xml input source will take ownership + + if (fstm->open (this->file_name_.c_str ()) == 0) + { + // InputSource takes ownership + ACEXML_InputSource input (fstm); + + ACEXML_Parser parser; + parser.setContentHandler (this); + parser.setDTDHandler (this); + parser.setErrorHandler (this); + parser.setEntityResolver (this); + + ACEXML_TRY_NEW_ENV + { + parser.parse (&input ACEXML_ENV_ARG_PARAMETER); + ACEXML_TRY_CHECK; + } + ACEXML_CATCH (ACEXML_Exception, ex) + { + // The only way to find out what it is, it to let it print itself, so... + ACE_ERROR ((LM_ERROR, "Error during load of \"%s\".\n Will try backup file.\n", this->file_name_.c_str ())); + ex.print (); + result = false; + } + ACEXML_ENDTRY; + } + else + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n Will try backup file.\n"), file_name_.c_str())); + result = false; + } + } + + if (! result) + { + this->file_name_ = base_name; + this->file_name_ += ".000"; + result = (0 == ACE_OS::access (this->file_name_.c_str (), 4)); + } + return result; + } + + //virtual + void + XML_Loader::load (Topology_Object *root ACE_ENV_ARG_DECL) + { + ACE_ASSERT (root != 0); + this->live_ = true; + + ACEXML_FileCharStream* fstm = new ACEXML_FileCharStream; + // xml input source will take ownership + + if (fstm->open (this->file_name_.c_str ()) == 0) + { + // InputSource takes ownership + ACEXML_InputSource input (fstm); + + ACEXML_Parser parser; + parser.setContentHandler (this); + parser.setDTDHandler (this); + parser.setErrorHandler (this); + parser.setEntityResolver (this); + + ACEXML_TRY_NEW_ENV + { + object_stack_.push (root); + parser.parse (&input ACEXML_ENV_ARG_PARAMETER); + ACEXML_TRY_CHECK; + ACE_ASSERT (object_stack_.size () == 1); + Topology_Object* cur; + object_stack_.pop (cur); + } + ACEXML_CATCH (ACEXML_Exception, ex) + { + // The only way to find out what it is, it to let it print itself, so... + ACE_ERROR ((LM_ERROR, "Error during load of \"%s\".\n", this->file_name_.c_str ())); + ex.print (); + ACE_THROW(CORBA::INTERNAL()); + } + ACEXML_ENDTRY; + } + else + { + ACE_DEBUG((LM_DEBUG, ACE_TEXT("Unable to open the XML input file: %s.\n"), file_name_.c_str())); + ACE_THROW(CORBA::INTERNAL()); + } + } + + void + XML_Loader::startElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name, + ACEXML_Attributes* xml_attrs ACEXML_ENV_ARG_DECL) + ACE_THROW_SPEC ( (ACEXML_SAXException)) + { + ACE_ASSERT (name != 0); + ACE_ASSERT (xml_attrs != 0); + if (this->live_) + { + ACE_ASSERT (object_stack_.size () > 0); + Topology_Object* cur; + if (object_stack_.top (cur) == 0) + { + ACE_TRY_NEW_ENV + { + NVPList attrs; + CORBA::Long id = makeNVPList (attrs, xml_attrs); + + if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO, + ACE_TEXT("(%P|%t) XML_Loader: Element %s\n"), + name + )); + + ACE_CString cname (name); + Topology_Object* next = cur->load_child ( + cname, id, attrs ACE_ENV_ARG_PARAMETER); + ACE_ASSERT(next != 0); + ACE_TRY_CHECK; + object_stack_.push (next); + } + ACE_CATCHANY + { + ACEXML_THROW (ACEXML_SAXException (ACE_ANY_EXCEPTION._info ().c_str ())); + } + ACE_ENDTRY; + } + } + } + + void + XML_Loader::endElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name ACEXML_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ( (ACEXML_SAXException)) + { + ACE_UNUSED_ARG (name); + if (this->live_) + { + ACE_ASSERT (object_stack_.size () > 0); + if (DEBUG_LEVEL > 5) ACE_DEBUG ((LM_INFO, + ACE_TEXT("(%P|%t) XML_Loader: End Element %s\n"), + name + )); + Topology_Object* cur; + object_stack_.pop (cur); + } + } + +} /* namespace TAO_NOTIFY */ + +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Unbounded_Stack<TAO_NOTIFY::Topology_Object*>; +template class ACE_Node<TAO_NOTIFY::Topology_Object*>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Unbounded_Stack<TAO_NOTIFY::Topology_Object*> +#pragma instantiate ACE_Node<TAO_NOTIFY::Topology_Object*> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h new file mode 100644 index 00000000000..3dcb9206caa --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Loader.h @@ -0,0 +1,86 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Loader.h + * + * $Id$ + * + * A topology saver class that outputs XML. + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_LOADER_H +#define XML_LOADER_H +#include /**/ "ace/pre.h" +#include /**/ "ace/config-all.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "Topology_Loader.h" + +#include "ACEXML/common/DefaultHandler.h" +#include "ACEXML/parser/parser/Parser.h" +#include "ACEXML/common/FileCharStream.h" + +#include "tao/corba.h" + +#include "ace/streams.h" + +namespace TAO_NOTIFY +{ + + /// \brief Load Notification Service Topology from an XML file. +class XML_Loader : public ACEXML_DefaultHandler , public Topology_Loader +{ +public: + /// The constructor. + XML_Loader (); + + virtual ~XML_Loader (); + + /// Open a file and perform preliminary validation to determine whether + /// the file is complete and valid. + bool open (const ACE_CString & file_name); + + /////////////////////////////////// + // Override Topology_Loader methods + // see Topology_Loader.h for documentation + virtual void load (Topology_Object *root ACE_ENV_ARG_DECL); + + + ///////////////////////////////////////// + // Override ACEXML_DefaultHandler methods + + virtual void startElement (const ACEXML_Char* namespaceURI, + const ACEXML_Char* localName, + const ACEXML_Char* qName, + ACEXML_Attributes* atts ACEXML_ENV_ARG_DECL) + ACE_THROW_SPEC ((ACEXML_SAXException)); + + virtual void endElement (const ACEXML_Char*, + const ACEXML_Char*, + const ACEXML_Char* name ACEXML_ENV_ARG_DECL_NOT_USED) + ACE_THROW_SPEC ((ACEXML_SAXException)); + + +private: + /// The name of the file from which data is read. + ACE_CString file_name_; + /// A stream representing our current output. + istream * input_; + + typedef ACE_Unbounded_Stack<Topology_Object*> TopoStack; + TopoStack object_stack_; + // if false, then we're just checking syntax of topology file. + bool live_; +}; + +} // namespace TAO_NOTIFY + +#include /**/ "ace/post.h" +#endif /* XML_LOADER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp new file mode 100644 index 00000000000..695e065311b --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.cpp @@ -0,0 +1,260 @@ +// $Id$ + +#include "XML_Saver.h" + +#include "ace/High_Res_Timer.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_unistd.h" + +namespace TAO_NOTIFY +{ + XML_Saver::XML_Saver(bool timestamp) + : output_ (0) + , close_out_ (false) + , backup_count_ (1) + , timestamp_ (timestamp) + { + } + + XML_Saver::~XML_Saver() + { + if (this->output_ != 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) XML_Saver warning close not called or failed\n") + )); + } + } + + void + XML_Saver::backup_file_name (char * file_path, int nfile) + { + ACE_OS::snprintf(file_path, MAXPATHLEN, "%s.%3.3d", + this->base_name_.c_str (), + nfile); + } + + void + XML_Saver::close (ACE_ENV_SINGLE_ARG_DECL) + { + if (this->close_out_ && this->output_ != 0) + { + this->end_object(0, "notification_service" ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + delete this->output_; + this->output_ = 0; + + // delete the oldest backup file (if it exists) + size_t nfile = this->backup_count_ - 1; + char old_path [MAXPATHLEN + 1]; + backup_file_name (old_path, nfile); + ACE_OS::unlink (old_path); + + while (nfile != 0) + { + char new_path [MAXPATHLEN + 1]; + nfile -= 1; + backup_file_name (new_path, nfile); + // this may fail, we don't care + ACE_OS::rename (new_path, old_path); + ACE_OS::strcpy (old_path, new_path); + } + // old_path now contains the name of the backup file + ACE_CString xml_name = this->base_name_; + xml_name += ".xml"; + + ACE_OS::rename (xml_name.c_str (), old_path); + + ACE_CString new_name = this->base_name_; + new_name += ".new"; + ACE_OS::rename (new_name.c_str (), xml_name.c_str ()); + } + this->output_ = 0; + } + + bool + XML_Saver::open(const ACE_CString & base_name, size_t backup_count) + { + this->base_name_ = base_name; + this->backup_count_ = backup_count; + if (base_name == "cout") + { + this->output_ = & cout; + this->close_out_ = false; + } + else if (base_name == "cerr") + { + this->output_ = & cerr; + this->close_out_ = false; + } + else + { + ACE_CString file_name = base_name; + file_name += ".new"; + + ofstream * fs = 0; + ACE_NEW_RETURN (fs, ofstream , false); + fs-> open (file_name.c_str()); + if (fs->is_open ()) + { + this->output_ = fs; + this->close_out_ = true; + } + else + { + delete fs; + ACE_ASSERT(this->output_ == 0); + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) XML_Saver unable to open %s\n"), + base_name.c_str())); + } + } + if (this->output_ != 0) + { + ostream& out = * this->output_; + + out << "<?xml version=\"1.0\"?>\n"; + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + bool changed = true; + NVPList attrs; + + ACE_Time_Value now = ACE_High_Res_Timer::gettimeofday(); + + ACE_UINT64 nowus = now.usec(); + static const ACE_UINT64 USECSPERSEC = 1000 * 1000; + ACE_UINT64 tmpus = now.sec(); + nowus += tmpus * USECSPERSEC; + + char nowusstr[128]; +#ifdef ACE_LACKS_LONGLONG_T + nowus.as_string(nowusstr); +#else + ACE_OS::sprintf(nowusstr, ACE_UINT64_FORMAT_SPECIFIER, nowus); +#endif /* ACE_LACKS_LONGLONG_T */ + + attrs.push_back(NVP("version", "1.0")); + if (this->timestamp_) + { + attrs.push_back(NVP("timestamp", nowusstr)); + } + this->begin_object(0, "notification_service", attrs, changed ACE_ENV_ARG_PARAMETER); + ACE_TRY_CHECK; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("(%P|%t) XML_Saver Unknown exception\n")); + delete this->output_; + this->output_ = 0; + } + ACE_ENDTRY; + } + return this->output_ != 0; + } + + bool XML_Saver::begin_object(CORBA::Long id, + const ACE_CString& type, + const NVPList& attrs, + bool /* changed */ + ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_ASSERT(this->output_ != 0); + ostream& out = * this->output_; + + out << indent_ << "<" << type; + if (id != 0) + { + // not all ostreams know what to do with a CORBA::Long + long lid = id; + out << " " << TOPOLOGY_ID_NAME << "=\"" << lid << "\""; + } + + char * buffer = 0; + size_t buffer_size = 0; + for (size_t idx = 0; idx < attrs.size(); idx++) + { + out << " " + << attrs[idx].name.c_str () + << "=\"" + << escape_string(buffer, buffer_size, attrs[idx].value.c_str ()) + << "\""; + } + delete [] buffer; + out << ">\n"; + this->indent_ += " "; + return true; + } + + void XML_Saver::end_object (CORBA::Long id, + const ACE_CString& type ACE_ENV_ARG_DECL_NOT_USED) + { + ACE_ASSERT(this->output_ != 0); + ACE_UNUSED_ARG (id); + ostream& out = * this->output_; + if (this->indent_.length() >= 2) + { + this->indent_ = this->indent_.substr(2); + } + // Note : We avoid flushing after every object by using \n instead of << endl; + out << indent_ << "</" << type << ">\n"; + } + + static const char escaped_amp[] = "&"; + static const char escaped_less[] = "<"; + static const char escaped_greater[] = ">"; + static const char escaped_apos[] = "'"; + static const char escaped_quote[] = """; + + char * + XML_Saver::escape_string(char *& buffer, size_t & size, const ACE_CString & str) + { + size_t len = str.length (); + size_t needed = len * (sizeof(escaped_quote)-1) + 1; + if (needed > size) + { + delete [] buffer; + buffer = new char [needed]; + size = needed; + } + size_t pos = 0; // position in output buffer + for (size_t stridx = 0; stridx < len; stridx++) + { + char curchar = str[stridx]; + if (curchar == '&') + { + strcpy (&buffer[pos], escaped_amp); + pos += sizeof (escaped_amp) -1; + } + else if (curchar == '<') + { + strcpy (&buffer[pos], escaped_less); + pos += sizeof (escaped_less) -1; + } + else if (curchar == '>') + { + strcpy (&buffer[pos], escaped_greater); + pos += sizeof (escaped_greater) -1; + } + else if (curchar == '\'') + { + strcpy (&buffer[pos], escaped_apos); + pos += sizeof (escaped_apos) -1; + } + else if (curchar == '\"') + { + strcpy (&buffer[pos], escaped_quote); + pos += sizeof (escaped_quote) -1; + } + else + { + buffer[pos++] = curchar; + } + } + buffer[pos++] = '\0'; + return buffer; + } + +} /* namespace TAO_NOTIFY */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h new file mode 100644 index 00000000000..1d5beff9e5e --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Saver.h @@ -0,0 +1,87 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Saver.h + * + * $Id$ + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_SAVER_H +#define XML_SAVER_H +#include /**/ "ace/pre.h" + +#include "Topology_Saver.h" + +#include "tao/corba.h" +#include "ace/streams.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_NOTIFY +{ + +/** + * \brief Save Notification Service Topology to an XML file. + */ +class XML_Saver : public Topology_Saver +{ +public: + /// Construct an XML_Saver. + /// Initialization is deferred to "open()" + XML_Saver (bool timestamp = true); + + virtual ~XML_Saver (); + + /// Open the output file. + /// \param file_name the fully qualified file name + /// \return true if successful + bool open (const ACE_CString & file_name, size_t backup_count); + + ////////////////////////////////// + // Override Topology_Saver methods + // see Topology_Saver.h for doc + virtual bool begin_object (CORBA::Long id, + const ACE_CString& type, + const NVPList& attrs, + bool changed + ACE_ENV_ARG_DECL); + + virtual void end_object (CORBA::Long id, + const ACE_CString& type + ACE_ENV_ARG_DECL); + + virtual void close (ACE_ENV_SINGLE_ARG_DECL); + +private: + void backup_file_name (char * file_path, int nfile); + + /// \return newstr to allow in-line use + char* escape_string(char *& newstr, size_t & size, const ACE_CString & str); + +private: + /// A stream representing our current output. + ostream * output_; + bool close_out_; + + /// the name of the output file + ACE_CString base_name_; + size_t backup_count_; + + /// true to enable timestamping + bool timestamp_; + + /// A string consisting of spaces that is our current indentation level. + ACE_CString indent_; + +}; + +} // namespace TAO_NOTIFY + +#include /**/ "ace/post.h" +#endif /* XML_SAVER_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp new file mode 100644 index 00000000000..e7f0eaae2fb --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.cpp @@ -0,0 +1,154 @@ +// $Id$ + +#include "XML_Topology_Factory.h" +#include "XML_Saver.h" +#include "XML_Loader.h" + +#include "tao/debug.h" +#include "ace/OS_NS_strings.h" +//#include "ace/Service_Object.h" + +namespace TAO_NOTIFY +{ + + XML_Topology_Factory::XML_Topology_Factory() + : save_base_path_ ("./Notification_Service_Topology") + , load_base_path_ ("./Notification_Service_Topology") + , backup_count_ (2) + , timestamp_ (true) + { + } + + // virtual + Topology_Saver* + XML_Topology_Factory::create_saver () + { + XML_Saver *saver = 0; + + ACE_NEW_RETURN (saver, XML_Saver (this->timestamp_), 0); + + if (! saver->open ( this->save_base_path_.c_str (), this->backup_count_)) + { + delete saver; + saver = 0; + } + return ACE_static_cast (Topology_Saver *, saver); + } + + // virtual + Topology_Loader* + XML_Topology_Factory::create_loader() + { + XML_Loader *loader = 0; + ACE_NEW_NORETURN(loader, XML_Loader); + + if (! loader->open(this->load_base_path_)) + { + delete loader; + loader = 0; + } + return ACE_static_cast (Topology_Loader *, loader); + } + + // virtual + int + XML_Topology_Factory::init (int argc, ACE_TCHAR *argv[]) + { + int result = 0; + bool verbose = false; + for (int narg = 0; narg < argc; ++narg) + { + ACE_TCHAR * av = argv[narg]; + if (ACE_OS::strcasecmp (av, "-v") == 0) + { + verbose = true; + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) Standard_Event_Persistence: -verbose\n") + )); + } + else if (ACE_OS::strcasecmp (av, "-base_path") == 0 && narg + 1 < argc) + { + this->save_base_path_ = argv[narg + 1]; + this->load_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -base_path: %s\n"), + this->save_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-save_base_path") == 0 && narg + 1 < argc) + { + this->save_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -save_base_path: %s\n"), + this->save_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-load_base_path") == 0 && narg + 1 < argc) + { + this->load_base_path_ = argv[narg + 1]; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -load_base_path: %s\n"), + this->load_base_path_.c_str () + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-backup_count") == 0 && narg + 1 < argc) + { + this->backup_count_ = ACE_OS::atoi(argv[narg + 1]); + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -file_count: %d\n"), + this->backup_count_ + )); + } + narg += 1; + } + else if (ACE_OS::strcasecmp (av, "-no_timestamp") == 0) + { + this->timestamp_ = false; + if (TAO_debug_level > 0 || verbose) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("(%P|%t) XML_TopologyFactory: Setting -no_timestamp\n") + )); + } + } + else + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%P|%t) Unknown parameter to XML Topology Factory: %s\n"), + argv[narg] + )); + result = -1; + } + } + return result; + } + + // virtual + int + XML_Topology_Factory::fini () + { + // nothing to do yet + return 0; + } + +ACE_FACTORY_DECLARE (TAO_Notify_Persist, XML_Topology_Factory) +ACE_FACTORY_DEFINE (TAO_Notify_Persist, XML_Topology_Factory) + + +} /* namespace TAO_NOTIFY */ + + diff --git a/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h new file mode 100644 index 00000000000..e063acdbc42 --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/XML_Topology_Factory.h @@ -0,0 +1,77 @@ +/* -*- C++ -*- */ + +//============================================================================= +/** + * @file XML_Topology_Factory.h + * + * $Id$ + * + * @author Jonathan Pollack <pollack_j@ociweb.com> + */ +//============================================================================= + +#ifndef XML_TOPOLOGY_FACTORY_H +#define XML_TOPOLOGY_FACTORY_H +#include /**/ "ace/pre.h" + +#include "Topology_Factory.h" +#include "notify_persist_export.h" + +#include "tao/corba.h" +#include "ace/SString.h" + + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +#pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +namespace TAO_NOTIFY +{ + + /** + * \brief Create XML topology savers and loaders + * + * Loaded by a svc.conf line like: + * dynamic Topology_Factory Service_Object* TAO_CosNotificationd:_make_XML_Topology_Factory() "[arguments]" + * where arguments are: + * -base_path Base path (directory and filename) for both saving and loading. + * .xml will be appended to the base path + * Default is ./Notification_Service_Topology + * -save_base_path Base path for saving. + * -load_base_path Base path for loading. + * -file_count How many backup copies to keep. Default is 1 + * -no_timestamp Disable timestamping (makes files diffable) + * Note: you can set both saving and storing to the same file using -base_path + * Or you can set them independently using -save_base_path + * and -load_base_path + * + */ + class TAO_Notify_Persist_Export XML_Topology_Factory : public Topology_Factory + { + public: + /// The constructor. + XML_Topology_Factory (); + + //////////////////////////////////// + // Override Topology_Factory methods + // documented in Topology_Factory.h + virtual Topology_Saver* create_saver (); + virtual Topology_Loader* create_loader(); + + //////////////////////////////// + // Override Share_Object methods + // documented in ace/Shared_Object.h + virtual int init (int argc, ACE_TCHAR *argv[]); + virtual int fini (); + + private: + ACE_CString save_base_path_; + ACE_CString load_base_path_; + size_t backup_count_; + bool timestamp_; + }; + +} // namespace TAO_NOTIFY + +#include /**/ "ace/post.h" +#endif /* XML_TOPOLOGY_FACTORY_H */ diff --git a/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h b/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h new file mode 100644 index 00000000000..a1672e8c3ca --- /dev/null +++ b/TAO/orbsvcs/orbsvcs/Notify/notify_persist_export.h @@ -0,0 +1,54 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TAO_Notify_Persist +// ------------------------------ +#ifndef TAO_NOTIFY_PERSIST_EXPORT_H +#define TAO_NOTIFY_PERSIST_EXPORT_H + +#include "ace/config-all.h" + +#if !defined (TAO_NOTIFY_PERSIST_HAS_DLL) +# define TAO_NOTIFY_PERSIST_HAS_DLL 1 +#endif /* ! TAO_NOTIFY_PERSIST_HAS_DLL */ + +#if defined (TAO_NOTIFY_PERSIST_HAS_DLL) && (TAO_NOTIFY_PERSIST_HAS_DLL == 1) +# if defined (TAO_NOTIFY_PERSIST_BUILD_DLL) +# define TAO_Notify_Persist_Export ACE_Proper_Export_Flag +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_NOTIFY_PERSIST_BUILD_DLL */ +# define TAO_Notify_Persist_Export ACE_Proper_Import_Flag +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_NOTIFY_PERSIST_BUILD_DLL */ +#else /* TAO_NOTIFY_PERSIST_HAS_DLL == 1 */ +# define TAO_Notify_Persist_Export +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARATION(T) +# define TAO_NOTIFY_PERSIST_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_NOTIFY_PERSIST_HAS_DLL == 1 */ + +// Set TAO_NOTIFY_PERSIST_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_NOTIFY_PERSIST_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_NOTIFY_PERSIST_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_NOTIFY_PERSIST_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_NOTIFY_PERSIST_NTRACE */ + +#if (TAO_NOTIFY_PERSIST_NTRACE == 1) +# define TAO_NOTIFY_PERSIST_TRACE(X) +#else /* (TAO_NOTIFY_PERSIST_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_NOTIFY_PERSIST_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_NOTIFY_PERSIST_NTRACE == 1) */ + +#endif /* TAO_NOTIFY_PERSIST_EXPORT_H */ + +// End of auto generated file. |