Remove dynamic exceptions
[anna.git] / include / anna / http / wims20 / Abstract.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_http_wims20_Abstract_hpp
10 #define anna_http_wims20_Abstract_hpp
11
12 #include <vector>
13
14 #include <anna/core/RuntimeException.hpp>
15 #include <anna/core/util/Recycler.hpp>
16
17 namespace anna {
18
19 namespace http {
20
21 namespace wims20 {
22
23 /**
24    Permite interpretar una URI según las recomendaciones de WIMS 2.0, lo que facilita
25    el desarrollo de aplicaciones integradas en Web 2.0; estas recomendaciones indican
26    cómo debe formarse la petición Abstract (REpresentational State Transfer) para permitir
27    el desarrollo de cualquier servicio.
28
29    El formato general de una URI según la recomendación de WIMS 2.0 es:
30
31    <p>
32 http://domain-openapis/path-openapis/serviceID/guid/other_possible_levels?query_parameters
33    </p>
34
35    Dónde los campos tienen siguen la siguiente especificación:
36    \li http://domain-openapis: Identifica el recurso del Open API. Formará parte de la configuración
37    de nuestro API (servicio) particular.
38    \li path-openapis: Recurso opcional que ajusta la ruta hacia los recursos de éste API. Formará parte
39    de la configuración de nuestro API (servicio) particular.
40    \li serviceID: Identificador de recurso.
41    \li guid: Identificador del usuario que solicita la petición.
42    \li other_possible_level: Opcionalmente se pueden indicar tantos niveles jerárquicos como fuera
43    necesario para el servicio.
44    \li query_parameters: Lista de parámetros. Si hay más de un parámetro se separará con '&'.
45 */
46 class Abstract {
47 public:
48   typedef std::vector <std::string*> other_level_container;
49   typedef other_level_container::iterator other_level_iterator;
50   typedef other_level_container::const_iterator const_other_level_iterator;
51
52   /**
53    * Los parámetros se ordenan en el mismo orden en que fueron indicados
54    * por eso no se guardan sobre un std::map, ya que al volcarlos sobre la
55    * cadena que actuará como URI aparecerían ordenados alfabéticamente y
56    * quizás el servidor no lo espera así.
57    */
58   typedef std::pair <std::string*, std::string*> parameter_pkv;
59   typedef std::vector <parameter_pkv> parameter_container;
60   typedef parameter_container::iterator parameter_iterator;
61   typedef parameter_container::const_iterator const_parameter_iterator;
62
63   /**
64    * Destructor
65    */
66   virtual ~Abstract();
67
68   /**
69    * Devuelve el campo \em domain-openapis establecido en el contructor.
70    * \return el campo \em domain-openapis establecido en el contructor.
71    */
72   const std::string& getDomain() const { return a_domain; }
73
74   /**
75    * Devuelve el campo \em path-openapis
76    * \return El campo \em path-openapis, puede ser NULL.
77    */
78   const std::string* getPath() const { return a_path; }
79
80   /**
81    * Devuelve el servicio de la OpenAPI.
82    * \param Identificador de servicio usado en la OpenAPI.
83    */
84   const std::string& getServiceID() const { return a_serviceID; }
85
86   /**
87    * Devuelve identificador de usuario que interacciona con el servicio.
88    * \return El identificador de usuario que interacciona con el servicio.
89    */
90   const std::string& getGUID() const { return a_guid; }
91
92   /**
93    * Establece el servicio de la OpenAPI.
94    * \param serviceID Identificador de servicio usado en la OpenAPI.
95    */
96   void setServiceID(const std::string& serviceID) { a_serviceID = serviceID; a_fixedPart.clear(); }
97
98   /**
99    * Establece el identificador de usuario que interacciona con el servicio.
100    * \param guid Identificador de usuario. Dónde por usuario se entiende cualquier elemento
101    * que pueda intereccionar con nuestro servicio
102    */
103   void setGUID(const std::string& guid) { a_guid = guid; a_fixedPart.clear(); }
104
105   /**
106    * Devuelve \em true si la estructura contiene parámetros o \em false en otro caso.
107    * \return \em true si la estructura contiene parámetros o \em false en otro caso.
108    */
109   bool hasParameters() const { return a_parameters != NULL && a_parameters->empty() == false; }
110
111   /**
112    * Devuelve \em true si la estructura contiene niveles opcionales o \em false en otro caso.
113    * \return \em true si la estructura contiene niveles opcionales o \em false en otro caso.
114    */
115   bool hasOtherLevels() const { return a_otherLevels != NULL && a_otherLevels->empty() == false; }
116
117   /**
118    * Limpia el contenido asociado al parámetro \em other_possible_level. Sólo debería
119    * invocarse a este método en caso de que el servicio destino de la petición haya cambiado.
120    */
121   virtual void clearOtherLevels() ;
122
123   /**
124    * Limpia el contenido asociado a los parámetros. Sólo debería invocarse a éste método en caso
125    * de que el número de parámetros a enviar sea distinto al de la petición anterior.
126    * Si son los mismos parámetros con el mismo nombre, deberíamos reutilizar el máximo número
127    * de veces.
128    */
129   virtual void clearParameters() ;
130
131   /**
132    * Inicializa los toda la información asociada a esta instancia.
133    */
134   void clear() {
135     clearOtherLevels();
136     clearParameters();
137   }
138
139   /**
140    * Devuelce una cadena con la información relevante sobre esta clase.
141    * \return una cadena con la información relevante sobre esta clase.
142    */
143   std::string asString() const ;
144
145   /**
146    * Devuelve un iterator al comienzo de la lista de niveles adicionales.
147    * \return un iterator al comienzo de la lista de niveles adicionales.
148    * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
149    */
150   other_level_iterator other_level_begin() { return a_otherLevels->begin(); }
151
152   /**
153    * Devuelve un iterator al final de la lista de niveles adicionales.
154    * \return un iterator al final de la lista de niveles adicionales.
155    * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
156    */
157   other_level_iterator other_level_end() { return a_otherLevels->end(); }
158
159   /**
160    * Devuelve el valor asociado al iterador.
161    * \param ii Iterador sobre los niveles opcionales.
162    * \return el valor asociado al iterador.
163    */
164   static std::string* otherLevel(other_level_iterator ii) { return *ii; }
165
166   /**
167    * Devuelve un iterator al comienzo de la lista de niveles adicionales.
168    * \return un iterator al comienzo de la lista de niveles adicionales.
169    * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
170    */
171   const_other_level_iterator other_level_begin() const { return a_otherLevels->begin(); }
172
173   /**
174    * Devuelve un iterator al final de la lista de niveles adicionales.
175    * \return un iterator al final de la lista de niveles adicionales.
176    * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
177    */
178   const_other_level_iterator other_level_end() const { return a_otherLevels->end(); }
179
180   /**
181    * Devuelve el valor asociado al iterador.
182    * \param ii Iterador sobre los niveles opcionales.
183    * \return el valor asociado al iterador.
184    */
185   static const std::string& otherLevel(const_other_level_iterator ii) { return **ii; }
186
187   /**
188    * Devuelve un iterator al comienzo de la lista de niveles adicionales.
189    * \return un iterator al comienzo de la lista de niveles adicionales.
190    * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
191    */
192   const_parameter_iterator parameter_begin() const { return a_parameters->begin(); }
193
194   /**
195    * Devuelve un iterator al final de la lista de niveles adicionales.
196    * \return un iterator al final de la lista de niveles adicionales.
197    * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
198    */
199   const_parameter_iterator parameter_end() const { return a_parameters->end(); }
200
201   /**
202    * Devuelve el nombre del parámetro asociado al iterador.
203    * \param ii Iterador sobre los niveles opcionales.
204    * \return el nombre del parámetro asociado al iterador.
205    */
206   static const std::string& parameter_name(const_parameter_iterator ii) { return *(ii->first); }
207
208   /**
209    * Devuelve el valor del parámetro asociado al iterador.
210    * \param ii Iterador sobre los niveles opcionales.
211    * \return el valor del parámetro asociado al iterador.
212    */
213   static const std::string& parameter_value(const_parameter_iterator ii) { return *(ii->second); }
214
215 protected:
216   other_level_container* a_otherLevels;
217   parameter_container* a_parameters;
218
219   /**
220    * Contructor indicando el parámetro opcional \em path-openapis. Estos dos parámetros se obtendrá como
221    * parte de la configuración de nuestro sistema.
222    * \param domain: Identifica el recurso del OpenAPI.
223    * \param path: Parámetro opcional que ajusta la ruta hacia los recusos de éste API.
224    */
225   Abstract(const char* whatis, const std::string& domain, const std::string& path);
226
227   /**
228    * Constructor que no usará el parámetro opcional \em path-openapis. Este parámetro se obtendrá como
229    * parte de la configuración de nuestro sistema.
230    * \param domain: Identifica el recurso del OpenAPI.
231    */
232   explicit Abstract(const char* whatis, const std::string& domain);
233
234   /**
235    * Calcula la parte fija de la petición en base a #calculeShortFixedPart, el \em serviceID y el \em GUID.
236    * Mientras estos dos últimos campos se mantengan constrantes, el resultado de este método no cambia.
237    * \return Una cadena con la parte fija de la petición.
238    */
239   const std::string& calculeFixedPart() noexcept(false);
240
241   /**
242    * Calcula la parte fija corta de la petición. Tiene en cuenta el \em domain-openapis y si existe
243    * el path-openapis. Si fuera necesario incluye el identificador de protocolo "http://".
244    * \return Una cadena con la parte fija corta de la petición.
245    */
246   const std::string& calculeShortFixedPart() noexcept(false);
247
248   /**
249    * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
250    * \warning Exclusivamente uso interno.
251    */
252   std::string* createString() noexcept(false) { return a_string_pool.create(); }
253
254   /**
255    * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
256    * \warning Exclusivamente uso interno.
257    */
258   std::string* createString(const char* value) noexcept(false) {
259     std::string* result = a_string_pool.create();
260     *result = value;
261     return result;
262   }
263
264   /**
265    * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
266    * \warning Exclusivamente uso interno.
267    */
268   std::string* createString(const std::string& value) noexcept(false) { return createString(value.c_str()); }
269
270   /**
271    * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
272    * \warning Exclusivamente uso interno.
273    */
274   void destroyString(std::string* str) { a_string_pool.release(str); }
275
276   /**
277    * Amplía la lista de niveles.
278    * \param otherLevel Nombre del nivel con el que ampliar las lista.
279    */
280   void other_level_add(const std::string& otherLevel) noexcept(false);
281
282   /**
283    * Amplía la lista de parámetros con una nueva pareja (Nombre, Valor).
284    * \param name Nombre del parámetro a crear.
285    * \param value Valor asociado al parámetro.
286    */
287   void parameter_set(const std::string& name, const std::string& value) noexcept(false);
288
289   /**
290    * Devuelve un iterator al comienzo de la lista de niveles adicionales.
291    * \return un iterator al comienzo de la lista de niveles adicionales.
292    * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
293    */
294   parameter_iterator parameter_begin() { return a_parameters->begin(); }
295
296   /**
297    * Devuelve un iterator al final de la lista de niveles adicionales.
298    * \return un iterator al final de la lista de niveles adicionales.
299    * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
300    */
301   parameter_iterator parameter_end() { return a_parameters->end(); }
302
303   /**
304    * Devuelve el nombre del parámetro asociado al iterador.
305    * \param ii Iterador sobre los niveles opcionales.
306    * \return el nombre del parámetro asociado al iterador.
307    */
308   static std::string* parameter_name(parameter_iterator ii) { return ii->first; }
309
310   /**
311    * Devuelve el valor del parámetro asociado al iterador.
312    * \param ii Iterador sobre los niveles opcionales.
313    * \return el valor del parámetro asociado al iterador.
314    */
315   static std::string* parameter_value(parameter_iterator ii) { return ii->second; }
316
317   /**
318    * Concatena las cadenas recibidas teniendo en entre ambas debe de haber un carácter '/'.
319    */
320   static void appendWithSlash(std::string& target, const std::string& other) ;
321
322 private:
323   const std::string a_whatis;
324   const std::string a_domain;
325   std::string* a_path;
326   std::string a_serviceID;
327   std::string a_guid;
328   Recycler <std::string> a_string_pool;
329   std::string a_fixedPart;
330 };
331
332
333 }
334 }
335 }
336
337 #endif