Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Node.hh

Go to the documentation of this file.
00001 // $Id: Node.hh 1742 2010-11-04 14:51:56Z g0dil $
00002 //
00003 // Copyright (C) 2008
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00200 #ifndef HH_SENF_Scheduler_Console_Node_
00201 #define HH_SENF_Scheduler_Console_Node_ 1
00202 
00203 // Custom includes
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 //#include "Node.mpp"
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         // Types
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         // Types
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         // Types
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         // Types
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         // Types
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 //#include "Node.ct"
00814 #include "Node.cti"
00815 #endif
00816 
00817 
00818 // Local Variables:
00819 // mode: c++
00820 // fill-column: 100
00821 // comment-column: 40
00822 // c-file-style: "senf"
00823 // indent-tabs-mode: nil
00824 // ispell-local-dictionary: "american"
00825 // compile-command: "scons -u test"
00826 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research