--- Ice-1.2.0-orig/src/IceStorm/Scanner.l 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Scanner.l 2003-12-27 17:54:03.000000000 -0500 @@ -130,6 +130,10 @@ return ICE_STORM_GRAPH; } +"subscribers" { + return ICE_STORM_SUBSCRIBERS; +} + {WS}*(\\{WS}*{NL})? { size_t len = strlen(yytext); for(size_t i = 0; i < len; ++i) --- Ice-1.2.0-orig/src/IceStorm/TopicI.cpp 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/TopicI.cpp 2003-12-27 17:51:21.000000000 -0500 @@ -247,6 +247,21 @@ return c; } +IdentitySeq +IceStorm::TopicSubscribers::getSubscriberList() const +{ + IceUtil::Mutex::Lock sync(_subscribersMutex); + + IdentitySeq seq; + for (SubscriberList::const_iterator p = _subscribers.begin(); + p != _subscribers.end(); ++p) + { + seq.push_back((*p)->id()); + } + + return seq; +} + // // Incoming events from publishers. // @@ -573,6 +588,21 @@ return seq; } +IdentitySeq +TopicI::getSubscriberList(const Ice::Current &) const +{ + { + IceUtil::RecMutex::Lock sync(*this); + + if (_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + } + + return _subscribers->getSubscriberList(); +} + TopicLinkPrx TopicI::getLinkProxy(const Ice::Current&) { --- Ice-1.2.0-orig/src/IceStorm/TopicI.h 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/TopicI.h 2003-12-27 17:21:49.000000000 -0500 @@ -52,6 +52,7 @@ void remove(const Ice::ObjectPrx&); void publish(const EventPtr&); SubscriberList clearErrorList(); + IdentitySeq getSubscriberList() const; private: @@ -86,6 +87,7 @@ virtual void link(const TopicPrx&, Ice::Int, const Ice::Current&); virtual void unlink(const TopicPrx&, const Ice::Current&); virtual LinkInfoSeq getLinkInfoSeq(const Ice::Current&) const; + virtual IdentitySeq getSubscriberList(const Ice::Current &) const; virtual TopicLinkPrx getLinkProxy(const Ice::Current&); --- Ice-1.2.0-orig/src/IceStorm/Parser.cpp 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Parser.cpp 2003-12-27 18:24:13.000000000 -0500 @@ -54,6 +54,7 @@ "unlink FROM TO Unlink TO from FROM.\n" "graph DATA COST Construct the link graph as described in DATA with COST\n" "list [TOPICS] Display information on TOPICS or all topics.\n" + "subscribers TOPIC List TOPIC's current subscribers.\n" ; } @@ -380,6 +381,44 @@ } void +Parser::subscribers(const list& _args) +{ + list args = _args; + + try + { + while (!args.empty()) + { + string name = args.front(); + args.pop_front(); + cout << name << endl; + try + { + TopicPrx topic = _admin->retrieve(name); + IdentitySeq subs = topic->getSubscriberList(); + for (IdentitySeq::const_iterator p = subs.begin(); p != subs.end(); ++p) + { + cout << '\t' << p->name; + if (!p->category.empty()) + cout << '/' << p->category; + cout << endl; + } + } + catch (const NoSuchTopic&) + { + cout << "\tNo such topic " << name << endl; + } + } + } + catch (const Exception& ex) + { + ostringstream s; + s << ex; + error(s.str()); + } +} + +void Parser::getInput(char* buf, int& result, int maxSize) { if(!_commands.empty()) --- Ice-1.2.0-orig/src/IceStorm/Parser.h 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Parser.h 2003-12-27 18:01:49.000000000 -0500 @@ -75,6 +75,7 @@ void link(const std::list&); void unlink(const std::list&); void graph(const std::list&); + void subscribers(const std::list&); void getInput(char*, int&, int); void nextLine(); --- Ice-1.2.0-orig/src/IceStorm/Grammar.y 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Grammar.y 2003-12-27 17:55:31.000000000 -0500 @@ -47,6 +47,7 @@ %token ICE_STORM_LINK %token ICE_STORM_UNLINK %token ICE_STORM_GRAPH +%token ICE_STORM_SUBSCRIBERS %token ICE_STORM_STRING %% @@ -113,6 +114,10 @@ { parser->dolist($2); } +| ICE_STORM_SUBSCRIBERS strings ';' +{ + parser->subscribers($2); +} | error ';' { yyerrok; --- Ice-1.2.0-orig/src/IceStorm/Scanner.l 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Scanner.l 2003-12-27 17:54:03.000000000 -0500 @@ -130,6 +130,10 @@ return ICE_STORM_GRAPH; } +"subscribers" { + return ICE_STORM_SUBSCRIBERS; +} + {WS}*(\\{WS}*{NL})? { size_t len = strlen(yytext); for(size_t i = 0; i < len; ++i) --- Ice-1.2.0-orig/src/IceStorm/TopicI.cpp 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/TopicI.cpp 2003-12-27 17:51:21.000000000 -0500 @@ -247,6 +247,21 @@ return c; } +IdentitySeq +IceStorm::TopicSubscribers::getSubscriberList() const +{ + IceUtil::Mutex::Lock sync(_subscribersMutex); + + IdentitySeq seq; + for (SubscriberList::const_iterator p = _subscribers.begin(); + p != _subscribers.end(); ++p) + { + seq.push_back((*p)->id()); + } + + return seq; +} + // // Incoming events from publishers. // @@ -573,6 +588,21 @@ return seq; } +IdentitySeq +TopicI::getSubscriberList(const Ice::Current &) const +{ + { + IceUtil::RecMutex::Lock sync(*this); + + if (_destroyed) + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + } + + return _subscribers->getSubscriberList(); +} + TopicLinkPrx TopicI::getLinkProxy(const Ice::Current&) { --- Ice-1.2.0-orig/src/IceStorm/TopicI.h 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/TopicI.h 2003-12-27 17:21:49.000000000 -0500 @@ -52,6 +52,7 @@ void remove(const Ice::ObjectPrx&); void publish(const EventPtr&); SubscriberList clearErrorList(); + IdentitySeq getSubscriberList() const; private: @@ -86,6 +87,7 @@ virtual void link(const TopicPrx&, Ice::Int, const Ice::Current&); virtual void unlink(const TopicPrx&, const Ice::Current&); virtual LinkInfoSeq getLinkInfoSeq(const Ice::Current&) const; + virtual IdentitySeq getSubscriberList(const Ice::Current &) const; virtual TopicLinkPrx getLinkProxy(const Ice::Current&); --- Ice-1.2.0-orig/src/IceStorm/Parser.cpp 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Parser.cpp 2003-12-27 18:50:37.000000000 -0500 @@ -54,6 +54,7 @@ "unlink FROM TO Unlink TO from FROM.\n" "graph DATA COST Construct the link graph as described in DATA with COST\n" "list [TOPICS] Display information on TOPICS or all topics.\n" + "subscribers TOPIC List TOPIC's current subscribers.\n" ; } @@ -380,6 +381,41 @@ } void +Parser::subscribers(const list& _args) +{ + list args = _args; + + try + { + while (!args.empty()) + { + string name = args.front(); + args.pop_front(); + cout << name << endl; + try + { + TopicPrx topic = _admin->retrieve(name); + IdentitySeq subs = topic->getSubscriberList(); + for (IdentitySeq::const_iterator p = subs.begin(); p != subs.end(); ++p) + { + cout << '\t' << *p << endl; + } + } + catch (const NoSuchTopic&) + { + cout << "\tNo such topic " << name << endl; + } + } + } + catch (const Exception& ex) + { + ostringstream s; + s << ex; + error(s.str()); + } +} + +void Parser::getInput(char* buf, int& result, int maxSize) { if(!_commands.empty()) --- Ice-1.2.0-orig/src/IceStorm/Parser.h 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Parser.h 2003-12-27 18:01:49.000000000 -0500 @@ -75,6 +75,7 @@ void link(const std::list&); void unlink(const std::list&); void graph(const std::list&); + void subscribers(const std::list&); void getInput(char*, int&, int); void nextLine(); --- Ice-1.2.0-orig/src/IceStorm/Grammar.y 2003-12-27 16:33:47.000000000 -0500 +++ Ice-1.2.0/src/IceStorm/Grammar.y 2003-12-27 17:55:31.000000000 -0500 @@ -47,6 +47,7 @@ %token ICE_STORM_LINK %token ICE_STORM_UNLINK %token ICE_STORM_GRAPH +%token ICE_STORM_SUBSCRIBERS %token ICE_STORM_STRING %% @@ -113,6 +114,10 @@ { parser->dolist($2); } +| ICE_STORM_SUBSCRIBERS strings ';' +{ + parser->subscribers($2); +} | error ';' { yyerrok;