ecpp.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003-2005 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27  */
28 
29 
30 #ifndef TNT_ECPP_H
31 #define TNT_ECPP_H
32 
33 #include <tnt/component.h>
34 #include <tnt/scope.h>
35 #include <tnt/sessionscope.h>
36 #include <tnt/httprequest.h>
37 #include <tnt/http.h>
38 #include <map>
39 #include <set>
40 
41 namespace tnt
42 {
43  class Urlmapper;
44  class Comploader;
45  class EcppSubComponent;
46 
48  // Subcompident
49  //
50  struct Subcompident : public tnt::Compident
51  {
52  std::string subname;
53 
54  Subcompident(const tnt::Compident& ci, const std::string& sub)
55  : tnt::Compident(ci),
56  subname(sub)
57  { }
58  Subcompident(const std::string& lib, const std::string& comp, const std::string& sub)
59  : tnt::Compident(lib, comp),
60  subname(sub)
61  { }
62 
63  explicit Subcompident(const std::string& ident);
64  std::string toString() const;
65  };
66 
68  // EcppComponent
69  //
70  class EcppComponent : public Component
71  {
72  friend class EcppSubComponent;
73 
74  Compident myident;
75  const Urlmapper& rootmapper;
76  Comploader& loader;
77 
78  typedef std::map<std::string, EcppSubComponent*> subcomps_type;
79  subcomps_type subcomps;
80 
81  virtual subcomps_type& getSubcomps() { return subcomps; }
82  virtual const subcomps_type& getSubcomps() const { return subcomps; }
83 
84  typedef std::set<std::string> libnotfound_type;
85  typedef std::set<Compident> compnotfound_type;
86 
87  protected:
88  virtual ~EcppComponent();
89 
90  void registerSubComp(const std::string& name, EcppSubComponent* comp);
91 
92  Component& fetchComp(const std::string& url) const;
93  Component& fetchComp(const Compident& ci) const;
94  Component& fetchComp(const Subcompident& ci) const;
95  Component* createComp(const Compident& ci) const;
96  Component* createComp(const std::string& url) const
97  { return createComp(Compident(url)); }
98 
100  template <typename compident_type,
101  typename parameter1_type,
102  typename parameter2_type>
103  unsigned callComp(const compident_type& ci, HttpRequest& request,
104  parameter1_type& p1, parameter2_type& p2)
105  { return fetchComp(ci).call(request, p1, p2); }
106 
107  template <typename compident_type,
108  typename parameter_type>
109  unsigned callComp(const compident_type& ci, HttpRequest& request,
110  parameter_type& p1)
111  { return fetchComp(ci).call(request, p1); }
112 
113  template <typename compident_type>
114  unsigned callComp(const compident_type& ci, HttpRequest& request)
115  { return fetchComp(ci).call(request); }
116 
118  template <typename compident_type,
119  typename parameter1_type>
120  std::string scallComp(const compident_type& ci, HttpRequest& request,
121  parameter1_type& p1)
122  { return fetchComp(ci).scall(request, p1); }
123 
124  template <typename compident_type>
125  std::string scallComp(const compident_type& ci, HttpRequest& request)
126  { return fetchComp(ci).scall(request); }
127 
128  const char* getData(const HttpRequest& request, const char* def) const;
129 
130  public:
131  EcppComponent(const Compident& ci, const Urlmapper& um, Comploader& cl);
132 
133  const Compident& getCompident() const { return myident; }
134 
135  EcppSubComponent& fetchSubComp(const std::string& sub) const;
136 
138  template <typename parameter1_type,
139  typename parameter2_type>
140  unsigned callSubComp(const std::string& sub, HttpRequest& request,
141  parameter1_type& p1,
142  parameter2_type& p2) const;
143 
144  template <typename parameter1_type>
145  unsigned callSubComp(const std::string& sub, HttpRequest& request,
146  parameter1_type& p1) const;
147 
149  template <typename parameter1_type>
150  std::string scallSubComp(const std::string& sub, HttpRequest& request,
151  parameter1_type& p1) const;
152  };
153 
155  // EcppSubComponent
156  //
158  {
159  EcppComponent& main;
160  std::string subcompname;
161 
162  virtual subcomps_type& getSubcomps()
163  { return main.getSubcomps(); }
164  virtual const subcomps_type& getSubcomps() const
165  { return main.getSubcomps(); }
166 
167  public:
168  EcppSubComponent(EcppComponent& p, const std::string& name)
169  : EcppComponent(p.myident, p.rootmapper, p.loader),
170  main(p),
171  subcompname(name)
172  {
173  p.registerSubComp(name, this);
174  }
175 
176  virtual void drop();
178  { return Subcompident(main.getCompident(), subcompname); }
179 
180  EcppComponent& getMainComponent() const { return main; }
181  };
182 
184  // inline methods
185  //
187  {
188  return dynamic_cast<EcppComponent&>(
189  fetchComp( static_cast<const Compident&>(ci) )
190  )
191  .fetchSubComp(ci.subname);
192  }
193 
194  template <typename parameter1_type,
195  typename parameter2_type>
197  const std::string& sub,
198  HttpRequest& request,
199  parameter1_type& p1,
200  parameter2_type& p2) const
201  { return fetchSubComp(sub).call(request, p1, p2); }
202 
203  template <typename parameter1_type>
205  const std::string& sub,
206  HttpRequest& request,
207  parameter1_type& p1) const
208  { return fetchSubComp(sub).call(request, p1); }
209 
211  template <typename parameter1_type>
213  const std::string& sub,
214  HttpRequest& request,
215  parameter1_type& p1) const
216  { return fetchSubComp(sub).scall(request, p1); }
217 
219  // scope-helper
220  //
221  inline std::string getPageScopePrefix(const Compident& id)
222  {
223  return id.toString();
224  }
225 
226  template <typename compident_type>
227  std::string getComponentScopePrefix(const compident_type& id)
228  {
229  return id.toString();
230  }
231 
233  {
234  return DECLINED;
235  }
236 
237  inline unsigned controllerCaller(tnt::Component* component, tnt::HttpRequest& request, tnt::HttpReply& reply, tnt::QueryParams& qparams)
238  {
239  return (*component)(request, reply, qparams);
240  }
241 
242 }
243 
244 #define TNT_VAR(scope, type, varname, key, construct) \
245  type* varname##_pointer; \
246  { \
247  const std::string varname##_scopekey = key; \
248  tnt::Scope& _scope = scope; \
249  varname##_pointer = _scope.get< type >(varname##_scopekey); \
250  if ( ! varname##_pointer ) \
251  _scope.put< type >(varname##_scopekey, \
252  varname##_pointer = new type construct); \
253  } \
254  type& varname = *varname##_pointer; \
255  { \
256  unsigned r = tnt::controllerCaller(varname##_pointer, request, reply, qparam); \
257  if (r != DECLINED && r != HTTP_OK) \
258  return r; \
259  }
260 
261 
262 #define TNT_SESSION_COMPONENT_VAR(type, varname, key, construct) \
263  TNT_VAR(request.getSessionScope(), type, varname, getComponentScopePrefix(getCompident()) + ":" key, construct)
264 
265 #define TNT_SESSION_PAGE_VAR(type, varname, key, construct) \
266  TNT_VAR(request.getSessionScope(), type, varname, getPageScopePrefix(getCompident()) + ":" key, construct)
267 
268 #define TNT_SESSION_GLOBAL_VAR(type, varname, key, construct) \
269  TNT_VAR(request.getSessionScope(), type, varname, key, construct)
270 
271 #define TNT_SECURE_SESSION_COMPONENT_VAR(type, varname, key, construct) \
272  TNT_VAR(request.getSecureSessionScope(), type, varname, getComponentScopePrefix(getCompident()) + ":" key, construct)
273 
274 #define TNT_SECURE_SESSION_PAGE_VAR(type, varname, key, construct) \
275  TNT_VAR(request.getSecureSessionScope(), type, varname, getPageScopePrefix(getCompident()) + ":" key, construct)
276 
277 #define TNT_SECURE_SESSION_GLOBAL_VAR(type, varname, key, construct) \
278  TNT_VAR(request.getSecureSessionScope(), type, varname, key, construct)
279 
280 #define TNT_APPLICATION_COMPONENT_VAR(type, varname, key, construct) \
281  TNT_VAR(request.getApplicationScope(), type, varname, getComponentScopePrefix(getCompident()) + ":" key, construct)
282 
283 #define TNT_APPLICATION_PAGE_VAR(type, varname, key, construct) \
284  TNT_VAR(request.getApplicationScope(), type, varname, getPageScopePrefix(getCompident()) + ":" key, construct)
285 
286 #define TNT_APPLICATION_GLOBAL_VAR(type, varname, key, construct) \
287  TNT_VAR(request.getApplicationScope(), type, varname, key, construct)
288 
289 #define TNT_THREAD_COMPONENT_VAR(type, varname, key, construct) \
290  TNT_VAR(request.getThreadScope(), type, varname, getComponentScopePrefix(getCompident()) + ":" key, construct)
291 
292 #define TNT_THREAD_PAGE_VAR(type, varname, key, construct) \
293  TNT_VAR(request.getThreadScope(), type, varname, getPageScopePrefix(getCompident()) + ":" key, construct)
294 
295 #define TNT_THREAD_GLOBAL_VAR(type, varname, key, construct) \
296  TNT_VAR(request.getThreadScope(), type, varname, key, construct)
297 
298 #define TNT_REQUEST_COMPONENT_VAR(type, varname, key, construct) \
299  TNT_VAR(request.getRequestScope(), type, varname, getComponentScopePrefix(getCompident()) + ":" key, construct)
300 
301 #define TNT_REQUEST_PAGE_VAR(type, varname, key, construct) \
302  TNT_VAR(request.getRequestScope(), type, varname, getPageScopePrefix(getCompident()) + ":" key, construct)
303 
304 #define TNT_REQUEST_GLOBAL_VAR(type, varname, key, construct) \
305  TNT_VAR(request.getRequestScope(), type, varname, key, construct)
306 
307 #define TNT_PARAM(type, varname, key, construct) \
308  TNT_VAR(qparam.getScope(), type, varname, key, construct)
309 
310 #endif // TNT_ECPP_H
311