Node.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
191 #ifndef HH_SENF_Utils_Console_Node_
192 #define HH_SENF_Utils_Console_Node_ 1
193 
194 // Custom includes
195 #include <map>
196 #include <boost/shared_ptr.hpp>
197 #include <boost/weak_ptr.hpp>
198 #include <boost/enable_shared_from_this.hpp>
199 #include <boost/range/iterator_range.hpp>
200 #include <boost/any.hpp>
201 #include <senf/Utils/Tags.hh>
202 #include <senf/Utils/Exception.hh>
204 
205 //#include "Node.mpp"
206 //-/////////////////////////////////////////////////////////////////////////////////////////////////
207 
208 namespace senf {
209 namespace console {
210 
211  class LinkNode;
212  class DirectoryNode;
213  class CommandNode;
214 
215  namespace detail { struct NodeFactory {}; }
216 
218  DirectoryNode & root();
219 
228  void dump(std::ostream & os, DirectoryNode & dir=root());
229 
230  void moveChildren(DirectoryNode & from, DirectoryNode & to);
231 
232 
251  : public boost::enable_shared_from_this<GenericNode>
252  {
254  public:
255  //-////////////////////////////////////////////////////////////////////////
256  // Types
257 
258  typedef boost::shared_ptr<GenericNode> ptr;
259  typedef boost::shared_ptr<GenericNode const> cptr;
260  typedef boost::weak_ptr<GenericNode> weak_ptr;
261 
262  //-////////////////////////////////////////////////////////////////////////
263 
264  virtual ~GenericNode();
265 
266  std::string const & name() const;
267  boost::shared_ptr<DirectoryNode> parent() const;
268 
271  std::string path() const;
272 
274  std::string path(DirectoryNode const & root) const;
276 
279  ptr unlink();
280 
283  void rename(std::string const & newName);
285 
290  bool active() const;
291 
292  void help(std::ostream & output) const;
293  std::string shorthelp() const;
294 
295  ptr thisptr();
296  cptr thisptr() const;
297 
298  bool isChildOf(DirectoryNode & parent) const;
300 
303  bool operator== (GenericNode & other) const;
305  bool operator!= (GenericNode & other) const;
307 
308  bool isDirectory() const;
309  bool isLink() const;
310  bool isCommand() const;
311 
312  GenericNode const & followLink() const;
313  GenericNode & followLink();
314 
315  protected:
316  GenericNode();
317 
318  void name(std::string const & name);
319 
320 #ifndef DOXYGEN
321  private:
322 #else
323  public:
324 #endif
325  virtual void v_help(std::ostream & output) const = 0;
327 
329  virtual std::string v_shorthelp() const = 0;
331 
334  private:
335  std::string name_;
336  DirectoryNode * parent_;
337 
338  friend class DirectoryNode;
339  };
340 
348  class LinkNode
349  : public GenericNode
350  {
351  public:
352  //-////////////////////////////////////////////////////////////////////////
353  // Types
354 
355  typedef boost::shared_ptr<LinkNode> ptr;
356  typedef boost::shared_ptr<LinkNode const> cptr;
357  typedef boost::weak_ptr<LinkNode> weak_ptr;
358 
359  //-////////////////////////////////////////////////////////////////////////
361  //\{
362 
363  static ptr create(GenericNode & node);
364 
367  //\}
368  //-////////////////////////////////////////////////////////////////////////
369 
370  GenericNode & follow() const;
371 
372  protected:
373 
374  private:
375  explicit LinkNode(GenericNode & node);
376 
377  virtual void v_help(std::ostream &) const;
378  virtual std::string v_shorthelp() const;
379 
380  GenericNode::ptr node_;
381  };
382 
383  class SimpleCommandNode;
384 
406  class DirectoryNode : public GenericNode
407  {
409  typedef std::map<std::string, GenericNode::ptr> ChildMap;
410  public:
411  //-////////////////////////////////////////////////////////////////////////
412  // Types
413 
414  typedef boost::shared_ptr<DirectoryNode> ptr;
415  typedef boost::shared_ptr<DirectoryNode const> cptr;
416  typedef boost::weak_ptr<DirectoryNode> weak_ptr;
417 
418  typedef boost::iterator_range<ChildMap::const_iterator> ChildrenRange;
419  typedef ChildMap::const_iterator child_iterator;
420 
423 
424  //-////////////////////////////////////////////////////////////////////////
426  //\{
427 
428  static ptr create();
429 
431  ~DirectoryNode();
432 
433  //\}
434  //-////////////////////////////////////////////////////////////////////////
436  //\{
437 
438  template <class NodeType>
439  NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
441 
447  template <class NodeType>
448  NodeType & add(std::string const & name, NodeType & node,
449  typename boost::enable_if< boost::is_convertible<NodeType &, GenericNode &> >::type * = 0);
450 
451  template <class Factory>
452  typename Factory::result_type add(std::string const & name, Factory const & factory,
453  typename boost::enable_if< boost::is_convertible<Factory const &, detail::NodeFactory const &> >::type * = 0);
455 
459  GenericNode::ptr remove(std::string const & name);
461 
465  GenericNode::ptr remove(std::string const & name, NoThrow_t);
467 
472  bool hasChild(std::string const & name) const;
474 
475  GenericNode & get(std::string const & name) const;
477 
479  GenericNode & getLink(std::string const & name) const;
481 
484  DirectoryNode & getDirectory(std::string const & name) const;
486 
492  DirectoryNode & operator[](std::string const & name) const;
494 
500  CommandNode & getCommand(std::string const & name) const;
502 
508  CommandNode & operator()(std::string const & name) const;
510 
516  ChildrenRange children() const;
517 
519  ChildrenRange completions(std::string const & s) const;
521 
523  //\}
524  //-////////////////////////////////////////////////////////////////////////
525 
526  DirectoryNode & doc(std::string const & doc);
527  DirectoryNode & shortdoc(std::string const & doc);
528 
529  ptr thisptr();
530  cptr thisptr() const;
531 
532  protected:
533  DirectoryNode();
534 
535  private:
536  void add(GenericNode::ptr node);
537  virtual void v_help(std::ostream & output) const;
538  virtual std::string v_shorthelp() const;
539 
540  ChildMap children_;
541  std::string doc_;
542  std::string shortdoc_;
543 
544  friend DirectoryNode & root();
545  };
546 
549  { UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
550 
563  class CommandNode : public GenericNode
564  {
566  public:
567  //-////////////////////////////////////////////////////////////////////////
568  // Types
569 
570  typedef boost::shared_ptr<CommandNode> ptr;
571  typedef boost::shared_ptr<CommandNode const> cptr;
572  typedef boost::weak_ptr<CommandNode> weak_ptr;
573 
574  //-////////////////////////////////////////////////////////////////////////
575 
576  void execute(std::ostream & output, ParseCommandInfo const & command) const;
578 
583  void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
584  const;
586 
592  void operator()(std::ostream & output, ParseCommandInfo const & command) const;
594 
599  void operator()(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
600  const;
601 
602  ptr thisptr();
603  cptr thisptr() const;
604 
605  protected:
606  CommandNode();
607 
608 #ifndef DOXYGEN
609  private:
610 #endif
611  virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
612  const = 0;
614 
620  private:
621  };
622 
636  {
638  public:
639  //-////////////////////////////////////////////////////////////////////////
640  // Types
641 
642  typedef boost::shared_ptr<SimpleCommandNode> ptr;
643  typedef boost::shared_ptr<SimpleCommandNode const> cptr;
644  typedef boost::weak_ptr<SimpleCommandNode> weak_ptr;
645 
646  typedef boost::function<void (std::ostream &, ParseCommandInfo const &)> Function;
647 
650 
651  //-////////////////////////////////////////////////////////////////////////
653  //\{
654 
655  static ptr create(Function const & fn);
656 
657  //\}
658  //-////////////////////////////////////////////////////////////////////////
659 
660  ptr thisptr();
661  cptr thisptr() const;
662 
663  SimpleCommandNode & doc(std::string const & doc);
664  SimpleCommandNode & shortdoc(std::string const & doc);
665 
666  protected:
667  SimpleCommandNode(Function const & fn);
668 
669  private:
670  virtual void v_help(std::ostream & output) const;
671  virtual std::string v_shorthelp() const;
672  virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
673  const;
674 
675 
676  Function fn_;
677  std::string doc_;
678  std::string shortdoc_;
679  };
680 
681  DirectoryNode & provideDirectory(DirectoryNode & dir, std::string const & name);
682 
716 namespace factory {
717 
727  : public detail::NodeFactory
728  {
729  public:
732 
734 
735  SimpleCommand const & doc(std::string const & doc) const;
737  SimpleCommand const & shortdoc(std::string const & doc) const;
739 
740  private:
741  SimpleCommandNode & create(DirectoryNode & dir, std::string const & name) const;
742 
744 
746  };
747 
761  class Directory
762  : public detail::NodeFactory
763  {
764  public:
767 
768  Directory();
769 
770  Directory const & doc(std::string const & doc) const;
772  Directory const & shortdoc(std::string const & doc) const;
774 
775  private:
776  DirectoryNode & create(DirectoryNode & dir, std::string const & name) const;
777 
778  DirectoryNode::ptr node_;
779 
781  };
782 
796  class Link
797  : public detail::NodeFactory
798  {
799  public:
802 
803  explicit Link(GenericNode & target);
804 
805  private:
806  LinkNode & create(DirectoryNode & dir, std::string const & name) const;
807 
808  LinkNode::ptr node_;
809 
811  };
812 
813 }
814 
815 }}
816 
817 //-/////////////////////////////////////////////////////////////////////////////////////////////////
818 #include "Node.cci"
819 //#include "Node.ct"
820 #include "Node.cti"
821 #endif
822 
823 
824 // Local Variables:
825 // mode: c++
826 // fill-column: 100
827 // comment-column: 40
828 // c-file-style: "senf"
829 // indent-tabs-mode: nil
830 // ispell-local-dictionary: "american"
831 // compile-command: "scons -u test"
832 // End:
boost::shared_ptr< SimpleCommandNode const > cptr
Definition: Node.hh:643
DirectoryNode node_type
Definition: Node.hh:421
SimpleCommandNode node_type
Definition: Node.hh:648
#define SENF_LOG_CLASS_AREA()
boost::shared_ptr< DirectoryNode > ptr
Definition: Node.hh:414
Config/console tree directory node.
Definition: Node.hh:406
boost::shared_ptr< LinkNode > ptr
Definition: Node.hh:355
boost::iterator_range< ChildMap::const_iterator > ChildrenRange
Definition: Node.hh:418
boost::weak_ptr< SimpleCommandNode > weak_ptr
Definition: Node.hh:644
boost::weak_ptr< GenericNode > weak_ptr
Definition: Node.hh:260
SimpleCommandNode & result_type
Definition: Node.hh:731
boost::shared_ptr< LinkNode const > cptr
Definition: Node.hh:356
boost::weak_ptr< CommandNode > weak_ptr
Definition: Node.hh:572
Definition: Config.hh:28
DirectoryNode & return_type
Definition: Node.hh:422
SimpleCommandNode & return_type
Definition: Node.hh:649
boost::shared_ptr< CommandNode const > cptr
Definition: Node.hh:571
Single parsed console command.
Definition: Parse.hh:363
boost::function< void(std::ostream &, ParseCommandInfo const &)> Function
Definition: Node.hh:646
void dump(std::ostream &os, DirectoryNode &dir=root())
Dump console directory structure.
Definition: Node.cc:52
boost::shared_ptr< GenericNode const > cptr
Definition: Node.hh:259
Most simple CommandNode implementation.
Definition: Node.hh:635
DirectoryNode factory.
Definition: Node.hh:761
Config/console tree link node.
Definition: Node.hh:348
ChildMap::const_iterator child_iterator
Definition: Node.hh:419
void moveChildren(DirectoryNode &from, DirectoryNode &to)
Definition: Node.cc:57
SimpleCommandNode factory.
Definition: Node.hh:726
DirectoryNode & root()
Get console root node.
Definition: Node.cc:26
NoThrow_t
DirectoryNode & result_type
Definition: Node.hh:766
Config/console tree command node.
Definition: Node.hh:563
boost::shared_ptr< CommandNode > ptr
Definition: Node.hh:565
unspecified_keyword_type name
Argument name.
boost::weak_ptr< LinkNode > weak_ptr
Definition: Node.hh:357
boost::weak_ptr< DirectoryNode > weak_ptr
Definition: Node.hh:416
Config/console node tree base-class.
Definition: Node.hh:250
DirectoryNode & provideDirectory(DirectoryNode &dir, std::string const &name)
boost::shared_ptr< DirectoryNode const > cptr
Definition: Node.hh:415
boost::shared_ptr< GenericNode > ptr
Definition: Node.hh:253
boost::shared_ptr< SimpleCommandNode > ptr
Definition: Node.hh:637
Exception: Unknown node name.
Definition: Node.hh:548