thread safe session class added using boost::mutex
[metaproxy-moved-to-github.git] / src / design.h
1
2 #ifndef DESIGN_H
3 #define DESIGN_H
4
5 #include <stdexcept>
6 #include <list>
7
8 #include <boost/thread/mutex.hpp>
9
10 namespace yp2 {
11
12     class Package;
13     
14     class Filter {
15     public:
16         virtual ~Filter(){};
17
18         ///sends Package off to next Filter, returns altered Package
19         virtual  Package & process(Package & package) const {
20             return package;
21         };
22         virtual  void configure(){};
23
24         /// get function - right val in assignment
25         std::string name() const {
26             return m_name;
27         }
28
29         /// set function - left val in assignment
30         std::string & name() {
31             return m_name;
32         }
33
34         /// set function - can be chained
35         Filter & name(const std::string & name){
36             m_name = name;
37             return *this;
38         }
39         
40     private:
41         std::string m_name;
42     };
43     
44     
45     class FilterException : public std::runtime_error {
46     public:
47         FilterException(const std::string message)
48             : std::runtime_error("FilterException: " + message){
49         };
50     };
51     
52   
53     class RouterException : public std::runtime_error {
54     public:
55         RouterException(const std::string message)
56             : std::runtime_error("RouterException: " + message){};
57     };
58   
59     
60     class Router {
61     public:
62         Router(){};
63         virtual ~Router(){};
64
65         /// determines next Filter to use from current Filter and Package
66         virtual const Filter *move(const Filter *filter,
67                                    const Package *package) const {
68             return 0;
69         };
70
71         /// re-read configuration of routing tables
72         virtual void configure(){};
73
74         /// add routing rule expressed as Filter to Router
75         virtual Router & rule(const Filter &filter){
76             return *this;
77         }
78     private:
79         /// disabled because class is singleton
80         Router(const Router &);
81
82         /// disabled because class is singleton
83         Router& operator=(const Router &);
84     };
85   
86     
87     class RouterChain : public Router {
88     public:
89         RouterChain(){};
90         virtual ~RouterChain(){};
91         virtual const Filter *move(const Filter *filter,
92                                    const Package *package) const {
93             std::list<const Filter *>::const_iterator it;
94             it = m_filter_list.begin();
95             if (filter)
96                 {
97                     for (; it != m_filter_list.end(); it++)
98                         if (*it == filter)
99                             {
100                                 it++;
101                                 break;
102                             }
103                 }
104             if (it == m_filter_list.end())
105                 {
106                     //throw RouterException("no routing rules known");
107                     return 0;
108                 }
109             return *it;
110         };
111         virtual void configure(){};
112         RouterChain & rule(const Filter &filter){
113             m_filter_list.push_back(&filter);
114             return *this;
115         }
116     protected:
117         std::list<const Filter *> m_filter_list;
118     private:
119         /// disabled because class is singleton
120         RouterChain(const RouterChain &);
121
122         /// disabled because class is singleton
123         RouterChain& operator=(const RouterChain &);
124     };
125   
126
127   class PackageException : public std::runtime_error {
128   public:
129       PackageException(const std::string message)
130           : std::runtime_error("PackageException: " + message){
131       };
132   };
133   
134   
135   class Package {
136   public:
137       
138       Package(unsigned long int id = 0, bool close = 0) 
139           : m_session_id(id),  m_session_close(close),
140           m_filter(0), m_router(0), m_data(0)  {}
141
142       /// send Package to it's next Filter defined in Router
143       Package & move() {
144           m_filter = m_router->move(m_filter, this);
145           if (m_filter)
146               return m_filter->process(*this);
147           else
148               return *this;
149           }
150       
151
152       /// get function - right val in assignment
153       unsigned int session_id() const {
154           return m_session_id;
155       }
156       
157       /// get function - right val in assignment
158       unsigned int session_close() const {
159           return m_session_close;
160       }
161    
162
163       /// get function - right val in assignment
164       unsigned int data() const {
165           return m_data;
166       }
167
168       /// set function - left val in assignment
169       unsigned int & data() {
170           return m_data;
171       }
172
173       /// set function - can be chained
174       Package & data(const unsigned int & data){
175           m_data = data;
176           return *this;
177       }
178       
179
180       //Router router() const {
181       //  return m_router;
182       //}
183
184       //Router & router() {
185       //  return m_router;
186       //}
187
188       /// set function - can be chained
189       Package & router(const Router &router){
190           m_filter = 0;
191           m_router = &router;
192           return *this;
193       }
194
195       
196   private:
197       unsigned long int m_session_id;
198       bool m_session_close;
199       const Filter *m_filter;
200       const Router *m_router;
201       unsigned int m_data;
202   };
203   
204
205   class Session 
206     {
207     public:
208       Session() : m_id(0){};
209       /// returns next id, global state of id protected by boost::mutex
210       long unsigned int id() {
211           boost::mutex::scoped_lock scoped_lock(m_mutex);
212           ++m_id;
213         return m_id;
214       };
215     private:
216       /// disabled because class is singleton
217       Session(const Session &);
218
219       /// disabled because class is singleton
220       Session& operator=(const Session &);
221
222       boost::mutex m_mutex;
223       unsigned long int m_id;
224       
225     };
226
227
228   
229 }
230
231 #endif
232 /*
233  * Local variables:
234  * c-basic-offset: 4
235  * indent-tabs-mode: nil
236  * End:
237  * vim: shiftwidth=4 tabstop=8 expandtab
238  */