1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_http_wims20_Abstract_hpp
38 #define anna_http_wims20_Abstract_hpp
42 #include <anna/core/RuntimeException.hpp>
43 #include <anna/core/util/Recycler.hpp>
52 Permite interpretar una URI según las recomendaciones de WIMS 2.0, lo que facilita
53 el desarrollo de aplicaciones integradas en Web 2.0; estas recomendaciones indican
54 cómo debe formarse la petición Abstract (REpresentational State Transfer) para permitir
55 el desarrollo de cualquier servicio.
57 El formato general de una URI según la recomendación de WIMS 2.0 es:
60 http://domain-openapis/path-openapis/serviceID/guid/other_possible_levels?query_parameters
63 Dónde los campos tienen siguen la siguiente especificación:
64 \li http://domain-openapis: Identifica el recurso del Open API. Formará parte de la configuración
65 de nuestro API (servicio) particular.
66 \li path-openapis: Recurso opcional que ajusta la ruta hacia los recursos de éste API. Formará parte
67 de la configuración de nuestro API (servicio) particular.
68 \li serviceID: Identificador de recurso.
69 \li guid: Identificador del usuario que solicita la petición.
70 \li other_possible_level: Opcionalmente se pueden indicar tantos niveles jerárquicos como fuera
71 necesario para el servicio.
72 \li query_parameters: Lista de parámetros. Si hay más de un parámetro se separará con '&'.
76 typedef std::vector <std::string*> other_level_container;
77 typedef other_level_container::iterator other_level_iterator;
78 typedef other_level_container::const_iterator const_other_level_iterator;
81 * Los parámetros se ordenan en el mismo orden en que fueron indicados
82 * por eso no se guardan sobre un std::map, ya que al volcarlos sobre la
83 * cadena que actuará como URI aparecerían ordenados alfabéticamente y
84 * quizás el servidor no lo espera así.
86 typedef std::pair <std::string*, std::string*> parameter_pkv;
87 typedef std::vector <parameter_pkv> parameter_container;
88 typedef parameter_container::iterator parameter_iterator;
89 typedef parameter_container::const_iterator const_parameter_iterator;
97 * Devuelve el campo \em domain-openapis establecido en el contructor.
98 * \return el campo \em domain-openapis establecido en el contructor.
100 const std::string& getDomain() const throw() { return a_domain; }
103 * Devuelve el campo \em path-openapis
104 * \return El campo \em path-openapis, puede ser NULL.
106 const std::string* getPath() const throw() { return a_path; }
109 * Devuelve el servicio de la OpenAPI.
110 * \param Identificador de servicio usado en la OpenAPI.
112 const std::string& getServiceID() const throw() { return a_serviceID; }
115 * Devuelve identificador de usuario que interacciona con el servicio.
116 * \return El identificador de usuario que interacciona con el servicio.
118 const std::string& getGUID() const throw() { return a_guid; }
121 * Establece el servicio de la OpenAPI.
122 * \param serviceID Identificador de servicio usado en la OpenAPI.
124 void setServiceID(const std::string& serviceID) throw() { a_serviceID = serviceID; a_fixedPart.clear(); }
127 * Establece el identificador de usuario que interacciona con el servicio.
128 * \param guid Identificador de usuario. Dónde por usuario se entiende cualquier elemento
129 * que pueda intereccionar con nuestro servicio
131 void setGUID(const std::string& guid) throw() { a_guid = guid; a_fixedPart.clear(); }
134 * Devuelve \em true si la estructura contiene parámetros o \em false en otro caso.
135 * \return \em true si la estructura contiene parámetros o \em false en otro caso.
137 bool hasParameters() const throw() { return a_parameters != NULL && a_parameters->empty() == false; }
140 * Devuelve \em true si la estructura contiene niveles opcionales o \em false en otro caso.
141 * \return \em true si la estructura contiene niveles opcionales o \em false en otro caso.
143 bool hasOtherLevels() const throw() { return a_otherLevels != NULL && a_otherLevels->empty() == false; }
146 * Limpia el contenido asociado al parámetro \em other_possible_level. Sólo debería
147 * invocarse a este método en caso de que el servicio destino de la petición haya cambiado.
149 virtual void clearOtherLevels() throw();
152 * Limpia el contenido asociado a los parámetros. Sólo debería invocarse a éste método en caso
153 * de que el número de parámetros a enviar sea distinto al de la petición anterior.
154 * Si son los mismos parámetros con el mismo nombre, deberíamos reutilizar el máximo número
157 virtual void clearParameters() throw();
160 * Inicializa los toda la información asociada a esta instancia.
162 void clear() throw() {
168 * Devuelce una cadena con la información relevante sobre esta clase.
169 * \return una cadena con la información relevante sobre esta clase.
171 std::string asString() const throw();
174 * Devuelve un iterator al comienzo de la lista de niveles adicionales.
175 * \return un iterator al comienzo de la lista de niveles adicionales.
176 * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
178 other_level_iterator other_level_begin() throw() { return a_otherLevels->begin(); }
181 * Devuelve un iterator al final de la lista de niveles adicionales.
182 * \return un iterator al final de la lista de niveles adicionales.
183 * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
185 other_level_iterator other_level_end() throw() { return a_otherLevels->end(); }
188 * Devuelve el valor asociado al iterador.
189 * \param ii Iterador sobre los niveles opcionales.
190 * \return el valor asociado al iterador.
192 static std::string* otherLevel(other_level_iterator ii) throw() { return *ii; }
195 * Devuelve un iterator al comienzo de la lista de niveles adicionales.
196 * \return un iterator al comienzo de la lista de niveles adicionales.
197 * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
199 const_other_level_iterator other_level_begin() const throw() { return a_otherLevels->begin(); }
202 * Devuelve un iterator al final de la lista de niveles adicionales.
203 * \return un iterator al final de la lista de niveles adicionales.
204 * \warning Sólo se puede invocar a este método si #hasOtherLevels devuelve \em true.
206 const_other_level_iterator other_level_end() const throw() { return a_otherLevels->end(); }
209 * Devuelve el valor asociado al iterador.
210 * \param ii Iterador sobre los niveles opcionales.
211 * \return el valor asociado al iterador.
213 static const std::string& otherLevel(const_other_level_iterator ii) throw() { return **ii; }
216 * Devuelve un iterator al comienzo de la lista de niveles adicionales.
217 * \return un iterator al comienzo de la lista de niveles adicionales.
218 * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
220 const_parameter_iterator parameter_begin() const throw() { return a_parameters->begin(); }
223 * Devuelve un iterator al final de la lista de niveles adicionales.
224 * \return un iterator al final de la lista de niveles adicionales.
225 * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
227 const_parameter_iterator parameter_end() const throw() { return a_parameters->end(); }
230 * Devuelve el nombre del parámetro asociado al iterador.
231 * \param ii Iterador sobre los niveles opcionales.
232 * \return el nombre del parámetro asociado al iterador.
234 static const std::string& parameter_name(const_parameter_iterator ii) throw() { return *(ii->first); }
237 * Devuelve el valor del parámetro asociado al iterador.
238 * \param ii Iterador sobre los niveles opcionales.
239 * \return el valor del parámetro asociado al iterador.
241 static const std::string& parameter_value(const_parameter_iterator ii) throw() { return *(ii->second); }
244 other_level_container* a_otherLevels;
245 parameter_container* a_parameters;
248 * Contructor indicando el parámetro opcional \em path-openapis. Estos dos parámetros se obtendrá como
249 * parte de la configuración de nuestro sistema.
250 * \param domain: Identifica el recurso del OpenAPI.
251 * \param path: Parámetro opcional que ajusta la ruta hacia los recusos de éste API.
253 Abstract(const char* whatis, const std::string& domain, const std::string& path);
256 * Constructor que no usará el parámetro opcional \em path-openapis. Este parámetro se obtendrá como
257 * parte de la configuración de nuestro sistema.
258 * \param domain: Identifica el recurso del OpenAPI.
260 explicit Abstract(const char* whatis, const std::string& domain);
263 * Calcula la parte fija de la petición en base a #calculeShortFixedPart, el \em serviceID y el \em GUID.
264 * Mientras estos dos últimos campos se mantengan constrantes, el resultado de este método no cambia.
265 * \return Una cadena con la parte fija de la petición.
267 const std::string& calculeFixedPart() throw(RuntimeException);
270 * Calcula la parte fija corta de la petición. Tiene en cuenta el \em domain-openapis y si existe
271 * el path-openapis. Si fuera necesario incluye el identificador de protocolo "http://".
272 * \return Una cadena con la parte fija corta de la petición.
274 const std::string& calculeShortFixedPart() throw(RuntimeException);
277 * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
278 * \warning Exclusivamente uso interno.
280 std::string* createString() throw(RuntimeException) { return a_string_pool.create(); }
283 * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
284 * \warning Exclusivamente uso interno.
286 std::string* createString(const char* value) throw(RuntimeException) {
287 std::string* result = a_string_pool.create();
293 * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
294 * \warning Exclusivamente uso interno.
296 std::string* createString(const std::string& value) throw(RuntimeException) { return createString(value.c_str()); }
299 * Optimiza la creación y liberación de cadenas que usa el proceso de interpretación continuamente.
300 * \warning Exclusivamente uso interno.
302 void destroyString(std::string* str) throw() { a_string_pool.release(str); }
305 * Amplía la lista de niveles.
306 * \param otherLevel Nombre del nivel con el que ampliar las lista.
308 void other_level_add(const std::string& otherLevel) throw(RuntimeException);
311 * Amplía la lista de parámetros con una nueva pareja (Nombre, Valor).
312 * \param name Nombre del parámetro a crear.
313 * \param value Valor asociado al parámetro.
315 void parameter_set(const std::string& name, const std::string& value) throw(RuntimeException);
318 * Devuelve un iterator al comienzo de la lista de niveles adicionales.
319 * \return un iterator al comienzo de la lista de niveles adicionales.
320 * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
322 parameter_iterator parameter_begin() throw() { return a_parameters->begin(); }
325 * Devuelve un iterator al final de la lista de niveles adicionales.
326 * \return un iterator al final de la lista de niveles adicionales.
327 * \warning Sólo se puede invocar a este método si #hasParameters devuelve \em true.
329 parameter_iterator parameter_end() throw() { return a_parameters->end(); }
332 * Devuelve el nombre del parámetro asociado al iterador.
333 * \param ii Iterador sobre los niveles opcionales.
334 * \return el nombre del parámetro asociado al iterador.
336 static std::string* parameter_name(parameter_iterator ii) throw() { return ii->first; }
339 * Devuelve el valor del parámetro asociado al iterador.
340 * \param ii Iterador sobre los niveles opcionales.
341 * \return el valor del parámetro asociado al iterador.
343 static std::string* parameter_value(parameter_iterator ii) throw() { return ii->second; }
346 * Concatena las cadenas recibidas teniendo en entre ambas debe de haber un carácter '/'.
348 static void appendWithSlash(std::string& target, const std::string& other) throw();
351 const std::string a_whatis;
352 const std::string a_domain;
354 std::string a_serviceID;
356 Recycler <std::string> a_string_pool;
357 std::string a_fixedPart;