Console: Implement ObjectDirectory proxy
[senf.git] / Console / Node.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Node public header */
25
26 #ifndef HH_Node_
27 #define HH_Node_ 1
28
29 // Custom includes
30 #include <map>
31 #include <boost/shared_ptr.hpp>
32 #include <boost/weak_ptr.hpp>
33 #include <boost/enable_shared_from_this.hpp>
34 #include <boost/utility.hpp>
35 #include <boost/range/iterator_range.hpp>
36 #include <boost/typeof/typeof.hpp>
37 #include <boost/type_traits/remove_reference.hpp>
38 #include "../Utils/Exception.hh"
39 #include "../Utils/mpl.hh"
40 #include "Parse.hh"
41
42 //#include "Node.mpp"
43 ///////////////////////////////hh.p////////////////////////////////////////
44
45 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
46
47 namespace senf {
48 namespace console {
49
50     class DirectoryNode;
51     class CommandNode;
52
53     /** \brief
54       */
55     class GenericNode 
56         : public boost::enable_shared_from_this<GenericNode>
57     {
58     public:
59         ///////////////////////////////////////////////////////////////////////////
60         // Types
61
62         typedef boost::shared_ptr<GenericNode> ptr;
63         typedef boost::shared_ptr<GenericNode const> cptr;
64         typedef boost::weak_ptr<GenericNode> weak_ptr;
65
66         ///////////////////////////////////////////////////////////////////////////
67
68         virtual ~GenericNode();
69
70         std::string const & name() const;
71         boost::shared_ptr<DirectoryNode> parent() const;
72
73         std::string path() const;
74
75         ptr unlink();
76
77         bool active() const;
78
79         void help(std::ostream & output) const;
80
81         ptr thisptr();
82         cptr thisptr() const;
83
84     protected:
85         GenericNode();
86
87         void name(std::string const & name);
88         static void name(GenericNode & node, std::string const & name);
89         void parent(DirectoryNode * parent);
90
91     private:
92         virtual void v_help(std::ostream & output) const = 0;
93
94         std::string name_;
95         DirectoryNode * parent_;
96
97         friend class intrusive_refcount_base;
98         friend class DirectoryNode;
99     };
100
101     class SimpleCommandNode;
102
103     template <class Object>
104     struct NodeCreateTraits
105     {
106         typedef BOOST_TYPEOF_TPL( senf_console_add_node( 
107                                       * static_cast<DirectoryNode *>(0),
108                                       * static_cast<std::string const *>(0),
109                                       * static_cast<Object const *>(0),
110                                       0) ) result_type;
111
112         typedef typename boost::remove_reference<result_type>::type NodeType;
113
114         struct Creator {
115             static NodeType & create(DirectoryNode & node, std::string const & name, 
116                                      Object const & ob);
117         };
118     };
119
120     /** \brief
121         ///\fixme Provide a default name for added nodes if 'name' is empty ?
122       */
123     class DirectoryNode : public GenericNode
124     {
125         typedef std::map<std::string, GenericNode::ptr> ChildMap;
126
127     public:
128         ///////////////////////////////////////////////////////////////////////////
129         // Types
130
131         typedef boost::shared_ptr<DirectoryNode> ptr;
132         typedef boost::shared_ptr<DirectoryNode const> cptr;
133         typedef boost::weak_ptr<DirectoryNode> weak_ptr;
134
135         typedef boost::iterator_range<ChildMap::const_iterator> ChildrenRange;
136         typedef ChildMap::const_iterator child_iterator;
137
138         ///////////////////////////////////////////////////////////////////////////
139         ///\name Structors and default members
140         ///\{
141
142         static std::auto_ptr<DirectoryNode> create();
143
144         ///\}
145         ///////////////////////////////////////////////////////////////////////////
146         ///\name Children
147         ///\{
148
149         template <class NodeType>
150         NodeType & add(std::string const & name, std::auto_ptr<NodeType> node);
151
152         template <class NodeType>
153         NodeType & add(std::string const & name, boost::shared_ptr<NodeType> node);
154
155         template <class Object>
156         typename NodeCreateTraits<Object>::NodeType & add (std::string const & name, 
157                                                            Object const & ob);
158
159         GenericNode::ptr remove(std::string const & name);
160
161         DirectoryNode & operator[](std::string const & name) const;
162         CommandNode & operator()(std::string const & name) const;
163         GenericNode & get(std::string const & name) const;
164
165         DirectoryNode & mkdir(std::string const & name);
166         
167         ChildrenRange children() const;
168
169         ///\}
170         ///////////////////////////////////////////////////////////////////////////
171
172         template <class ForwardRange>
173         GenericNode & traverse(ForwardRange const & range);
174
175         DirectoryNode & doc(std::string const & doc);
176
177         ptr thisptr();
178         cptr thisptr() const;
179
180     protected:
181         DirectoryNode();
182
183     private:
184         void add(GenericNode::ptr node);
185         virtual void v_help(std::ostream & output) const;
186
187         ChildMap children_;
188         std::string doc_;
189
190         friend DirectoryNode & root();
191     };
192
193     BOOST_TYPEOF_REGISTER_TYPE(DirectoryNode);
194
195     struct UnknownNodeNameException : public senf::Exception
196     { UnknownNodeNameException() : senf::Exception("Unknown node name") {}};
197
198     // We need this specialization since we cannot passe auto_ptr via const & !!
199     template <class Type>
200     struct NodeCreateTraits< std::auto_ptr<Type> >
201     {};
202
203     template <class Type>
204     struct NodeCreateTraits< boost::shared_ptr<Type> >
205     {};
206
207     /** \brief
208       */
209     class CommandNode : public GenericNode
210     {
211     public:
212         ///////////////////////////////////////////////////////////////////////////
213         // Types
214
215         typedef boost::shared_ptr<CommandNode> ptr;
216         typedef boost::shared_ptr<CommandNode const> cptr;
217         typedef boost::weak_ptr<CommandNode> weak_ptr;
218
219         typedef ParseCommandInfo::ArgumentsRange Arguments;
220
221         ///////////////////////////////////////////////////////////////////////////
222
223         virtual void operator()(std::ostream & output, Arguments const & arguments) = 0;
224
225         ptr thisptr();
226         cptr thisptr() const;
227
228     protected:
229         CommandNode();
230
231     private:
232     };
233
234     /** \brief
235       */
236     class SimpleCommandNode : public CommandNode
237     {
238     public:
239         ///////////////////////////////////////////////////////////////////////////
240         // Types
241
242         typedef boost::function<void (std::ostream &, Arguments const &)> Function;
243
244         ///////////////////////////////////////////////////////////////////////////
245
246         virtual void operator()(std::ostream & output, Arguments const & arguments);
247
248         ptr thisptr();
249         cptr thisptr() const;
250
251         static std::auto_ptr<SimpleCommandNode> create(Function const & fn);
252
253         SimpleCommandNode & doc(std::string const & doc);
254
255     protected:
256         SimpleCommandNode(Function const & fn);
257
258     private:
259         virtual void v_help(std::ostream & output) const;
260
261         Function fn_;
262         std::string doc_;
263     };
264
265     template <class Function>
266     SimpleCommandNode & senf_console_add_node(DirectoryNode & node, std::string const & name, 
267                                               Function const & fn, ...);
268
269     BOOST_TYPEOF_REGISTER_TYPE(SimpleCommandNode);
270
271     DirectoryNode & root();
272
273 }}
274
275 ///////////////////////////////hh.e////////////////////////////////////////
276 #include "Node.cci"
277 #include "Node.ct"
278 #include "Node.cti"
279 #endif
280
281 \f
282 // Local Variables:
283 // mode: c++
284 // fill-column: 100
285 // comment-column: 40
286 // c-file-style: "senf"
287 // indent-tabs-mode: nil
288 // ispell-local-dictionary: "american"
289 // compile-command: "scons -u test"
290 // End: