00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00200 #ifndef HH_SENF_Scheduler_Console_Node_
00201 #define HH_SENF_Scheduler_Console_Node_ 1
00202
00203
00204 #include <map>
00205 #include <boost/shared_ptr.hpp>
00206 #include <boost/weak_ptr.hpp>
00207 #include <boost/enable_shared_from_this.hpp>
00208 #include <boost/utility.hpp>
00209 #include <boost/range/iterator_range.hpp>
00210 #include <boost/any.hpp>
00211 #include <senf/Utils/Exception.hh>
00212 #include <senf/Utils/Logger/SenfLog.hh>
00213
00214
00215
00216
00217 namespace senf {
00218 namespace console {
00219
00220 class LinkNode;
00221 class DirectoryNode;
00222 class CommandNode;
00223
00224 namespace detail { struct NodeFactory {}; }
00225
00227 DirectoryNode & root();
00228
00237 void dump(std::ostream & os, DirectoryNode & dir=root());
00238
00256 class GenericNode
00257 : public boost::enable_shared_from_this<GenericNode>
00258 {
00259 SENF_LOG_CLASS_AREA();
00260 public:
00261
00262
00263
00264 typedef boost::shared_ptr<GenericNode> ptr;
00265 typedef boost::shared_ptr<GenericNode const> cptr;
00266 typedef boost::weak_ptr<GenericNode> weak_ptr;
00267
00268
00269
00270 virtual ~GenericNode();
00271
00272 std::string const & name() const;
00273 boost::shared_ptr<DirectoryNode> parent() const;
00274
00277 std::string path() const;
00278
00280 std::string path(DirectoryNode const & root) const;
00282
00285 ptr unlink();
00286
00290 bool active() const;
00291
00292 void help(std::ostream & output) const;
00293 std::string shorthelp() const;
00294
00295 ptr thisptr();
00296 cptr thisptr() const;
00297
00298 bool isChildOf(DirectoryNode & parent) const;
00300
00303 bool operator== (GenericNode & other) const;
00305 bool operator!= (GenericNode & other) const;
00307
00308 bool isDirectory() const;
00309 bool isLink() const;
00310 bool isCommand() const;
00311
00312 GenericNode const & followLink() const;
00313 GenericNode & followLink();
00314
00315 protected:
00316 GenericNode();
00317
00318 void name(std::string const & name);
00319
00320 #ifndef DOXYGEN
00321 private:
00322 #else
00323 public:
00324 #endif
00325 virtual void v_help(std::ostream & output) const = 0;
00327
00329 virtual std::string v_shorthelp() const = 0;
00331
00334 private:
00335 std::string name_;
00336 DirectoryNode * parent_;
00337
00338 friend class DirectoryNode;
00339 };
00340
00348 class LinkNode
00349 : public GenericNode
00350 {
00351 public:
00352
00353
00354
00355 typedef boost::shared_ptr<LinkNode> ptr;
00356 typedef boost::shared_ptr<LinkNode const> cptr;
00357 typedef boost::weak_ptr<LinkNode> weak_ptr;
00358
00359
00361
00362
00363 static ptr create(GenericNode & node);
00364
00367
00368
00369
00370 GenericNode & follow() const;
00371
00372 protected:
00373
00374 private:
00375 explicit LinkNode(GenericNode & node);
00376
00377 virtual void v_help(std::ostream &) const;
00378 virtual std::string v_shorthelp() const;
00379
00380 GenericNode::ptr node_;
00381 };
00382
00383 class SimpleCommandNode;
00384
00406 class DirectoryNode : public GenericNode
00407 {
00408 SENF_LOG_CLASS_AREA();
00409 typedef std::map<std::string, GenericNode::ptr> ChildMap;
00410 public:
00411
00412
00413
00414 typedef boost::shared_ptr<DirectoryNode> ptr;
00415 typedef boost::shared_ptr<DirectoryNode const> cptr;
00416 typedef boost::weak_ptr<DirectoryNode> weak_ptr;
00417
00418 typedef boost::iterator_range<ChildMap::const_iterator> ChildrenRange;
00419 typedef ChildMap::const_iterator child_iterator;
00420
00421 typedef DirectoryNode node_type;
00422 typedef DirectoryNode & return_type;
00423
00424
00426
00427
00428 static ptr create();
00429
00431 ~DirectoryNode();
00432
00433
00434
00436
00437
00438 template <class NodeType>
00439 NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
00441
00447 template <class NodeType>
00448 NodeType & add(std::string const & name, NodeType & node,
00449 typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
00450
00451 template <class Factory>
00452 typename Factory::result_type add(std::string const & name, Factory const & factory,
00453 typename boost::enable_if< boost::is_convertible<Factory const &, detail::NodeFactory const &> >::type * = 0);
00455
00459 GenericNode::ptr remove(std::string const & name);
00461
00466 bool hasChild(std::string const & name) const;
00468
00469 GenericNode & get(std::string const & name) const;
00471
00473 GenericNode & getLink(std::string const & name) const;
00475
00478 DirectoryNode & getDirectory(std::string const & name) const;
00480
00486 DirectoryNode & operator[](std::string const & name) const;
00488
00494 CommandNode & getCommand(std::string const & name) const;
00496
00502 CommandNode & operator()(std::string const & name) const;
00504
00510 ChildrenRange children() const;
00511
00513 ChildrenRange completions(std::string const & s) const;
00515
00517
00518
00519
00520 DirectoryNode & doc(std::string const & doc);
00521 DirectoryNode & shortdoc(std::string const & doc);
00522
00523 ptr thisptr();
00524 cptr thisptr() const;
00525
00526 protected:
00527 DirectoryNode();
00528
00529 private:
00530 void add(GenericNode::ptr node);
00531 virtual void v_help(std::ostream & output) const;
00532 virtual std::string v_shorthelp() const;
00533
00534 ChildMap children_;
00535 std::string doc_;
00536 std::string shortdoc_;
00537
00538 friend DirectoryNode & root();
00539 };
00540
00542 struct UnknownNodeNameException : public senf::Exception
00543 { UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
00544
00557 class CommandNode : public GenericNode
00558 {
00559 SENF_LOG_CLASS_AREA();
00560 public:
00561
00562
00563
00564 typedef boost::shared_ptr<CommandNode> ptr;
00565 typedef boost::shared_ptr<CommandNode const> cptr;
00566 typedef boost::weak_ptr<CommandNode> weak_ptr;
00567
00568
00569
00570 void execute(std::ostream & output, ParseCommandInfo const & command) const;
00572
00577 void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
00578 const;
00580
00586 void operator()(std::ostream & output, ParseCommandInfo const & command) const;
00588
00593 void operator()(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
00594 const;
00595
00596 ptr thisptr();
00597 cptr thisptr() const;
00598
00599 protected:
00600 CommandNode();
00601
00602 #ifndef DOXYGEN
00603 private:
00604 #endif
00605 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00606 const = 0;
00608
00614 private:
00615 };
00616
00629 class SimpleCommandNode : public CommandNode
00630 {
00631 SENF_LOG_CLASS_AREA();
00632 public:
00633
00634
00635
00636 typedef boost::shared_ptr<SimpleCommandNode> ptr;
00637 typedef boost::shared_ptr<SimpleCommandNode const> cptr;
00638 typedef boost::weak_ptr<SimpleCommandNode> weak_ptr;
00639
00640 typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
00641
00642 typedef SimpleCommandNode node_type;
00643 typedef SimpleCommandNode & return_type;
00644
00645
00647
00648
00649 static ptr create(Function const & fn);
00650
00651
00652
00653
00654 ptr thisptr();
00655 cptr thisptr() const;
00656
00657 SimpleCommandNode & doc(std::string const & doc);
00658 SimpleCommandNode & shortdoc(std::string const & doc);
00659
00660 protected:
00661 SimpleCommandNode(Function const & fn);
00662
00663 private:
00664 virtual void v_help(std::ostream & output) const;
00665 virtual std::string v_shorthelp() const;
00666 virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
00667 const;
00668
00669
00670 Function fn_;
00671 std::string doc_;
00672 std::string shortdoc_;
00673 };
00674
00675 DirectoryNode & provideDirectory(DirectoryNode & dir, std::string const & name);
00676
00710 namespace factory {
00711
00720 class SimpleCommand
00721 : public detail::NodeFactory
00722 {
00723 public:
00724 typedef SimpleCommandNode node_type;
00725 typedef SimpleCommandNode & result_type;
00726
00727 explicit SimpleCommand(SimpleCommandNode::Function fn);
00728
00729 SimpleCommand const & doc(std::string const & doc) const;
00731 SimpleCommand const & shortdoc(std::string const & doc) const;
00733
00734 private:
00735 SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const;
00736
00737 SimpleCommandNode::ptr node_;
00738
00739 friend class senf::console::DirectoryNode;
00740 };
00741
00755 class Directory
00756 : public detail::NodeFactory
00757 {
00758 public:
00759 typedef DirectoryNode node_type;
00760 typedef DirectoryNode & result_type;
00761
00762 Directory();
00763
00764 Directory const & doc(std::string const & doc) const;
00766 Directory const & shortdoc(std::string const & doc) const;
00768
00769 private:
00770 DirectoryNode & create(DirectoryNode & dir, std::string const & name) const;
00771
00772 DirectoryNode::ptr node_;
00773
00774 friend class senf::console::DirectoryNode;
00775 };
00776
00790 class Link
00791 : public detail::NodeFactory
00792 {
00793 public:
00794 typedef LinkNode node_type;
00795 typedef LinkNode & result_type;
00796
00797 explicit Link(GenericNode & target);
00798
00799 private:
00800 LinkNode & create(DirectoryNode & dir, std::string const & name) const;
00801
00802 LinkNode::ptr node_;
00803
00804 friend class senf::console::DirectoryNode;
00805 };
00806
00807 }
00808
00809 }}
00810
00811
00812 #include "Node.cci"
00813
00814 #include "Node.cti"
00815 #endif
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826