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_app_Application_hpp
38 #define anna_app_Application_hpp
42 #include <anna/core/RuntimeException.hpp>
58 Abstraccion de la aplicacion.
60 Mantiene la informacion de todos los recursos usados (version, titulo, linea de comandos,
61 threads, etc ...) por nuestras aplicaciones.
63 Slo puede haber una nica instancia de la aplicacio, que seria accesible mediante el
64 metodo anna::functions::getApp.
68 typedef std::vector <Component*>::iterator iterator;
69 typedef std::vector <Component*>::const_iterator const_iterator;
70 typedef std::vector <pid_t> pid_container;
71 typedef pid_container::iterator pid_iterator;
72 typedef pid_container::const_iterator const_pid_iterator;
77 @param shortName Nombre logico de esta instancia.
78 @param title Titulo de la aplicacion que aparecera al arrancar.
79 @param version version de este programa. Aconsejamos el forma X.YRZZ. Donde X es la
80 version principal, Y la version secundaria y ZZ es el numero de entrega realizada.
81 \param date Fecha de realizacion del componente. Normalmente sera el contenido de la macro __DATE__.
82 \param time Hora de realizacion del componente. Normalmente sera el contenido de la macro __TIME__.
84 Application(const char* shortName, const char* title, const char* version, const char* date = NULL, const char* time = NULL);
89 virtual ~Application() { a_components.clear(); }
93 Devuelve el nombre corto indicado en el constructor.
94 \return El nombre corto indicado en el constructor.
96 const char* getShortName() const throw() { return a_shortName; }
99 Devuelve la version indicado en el contructor de esta aplicacion.
100 \return La version indicado en el contructor de esta aplicacion.
102 const std::string& getVersion() const throw() { return a_version; }
105 Devuelve el titulo indicado en el contructor de esta aplicacion.
106 \return el titulo indicado en el contructor de esta aplicacion.
108 const std::string& getTitle() const throw() { return a_title; }
111 Devuelve el pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
112 @return El pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
114 pid_t getPid() const throw() { return a_pid; }
117 Activa la salida por pantalla del mensaje referente a la licencia GPL 3.0.
118 \warning Para que tenga efecto debe ser invocado antes de ejecutar el metodo Application::start.
120 void activateGeneralPublicLicense() throw() { a_enableGPL = true; }
123 * Crea un nuevo proceso a partir de este usando el metodo \em fork.
125 * Estrictamente este metodo retonara dos veces, una en el ambito del proceso que lo invoco y
126 * otra en el ambito del nuevo proceso, llamado proceso hijo.
128 * Si la duplicacion se realiza de forma correcta se invoca a los metodos #do_cloneChild y #do_cloneParent de nuestra
129 * aplicacion y Component::do_cloneChild y Component::do_cloneParent de cada uno de los componentes registrados.
131 * Para saber en cual de los procesos
132 * \return La instancia de la nueva aplicacion.
134 Application& clone() throw(RuntimeException);
137 Devuelve la instancia del componente que corresponde con el nombre recibido.
138 \return La instancia del componente que corresponde con el nombre recibido. Puede ser NULL si no
139 hay ningun componente asociado a la �ta aplicacion que corresponda con el nombre.
141 Component* find(const char* className) throw();
144 Inicializa los elementos propios de nuestra aplicacio, invoca al metodo #initialize
145 e invoca al metodo #run.
147 void start() throw(RuntimeException);
150 Devuelve un iterador al primer componente definido en la aplicacion.
151 \return un iterador al primer componente definido en la aplicacion.
153 const_iterator begin() const throw() { return a_components.begin(); }
156 Devuelve un iterador al primer componente definido en la aplicacion.
157 \return un iterador al primer componente definido en la aplicacion.
159 iterator begin() throw() { return a_components.begin(); }
162 Devuelve un iterador al ultimo componente definido en la aplicacion.
163 \return un iterador al ultimo componente definido en la aplicacion.
165 const_iterator end() const throw() { return a_components.end(); }
168 Devuelve un iterador al ultimo componente definido en la aplicacion.
169 \return un iterador al ultimo componente definido en la aplicacion.
171 iterator end() throw() { return a_components.end(); }
174 Vuelva un documento XML con el contexto de la aplicacion.
175 \param file Ruta completa del fichero en el que grabar el contexto de la aplicacion.
177 void writeContext(const std::string& file) throw(RuntimeException);
180 metodo que puede ser reescrito en las clases heredadas de Application y que nos
181 da la posibilidad de inicializar los elementos particulares de nuestra aplicacion.
182 Por defecto no realiza ninguna operacion.
183 \warning En el momento de invocar a esta funcin los componentes (\see Component) pueden no
186 virtual void initialize() throw(RuntimeException) {;}
189 Devuelve si esta aplicacion tiene soporto para comunicaciones entre procesos.
190 \return \em true si la aplicacion tiene soporta para comunicacion entre proceso o \em false
193 virtual bool supportCommunication() const throw() { return false; }
196 * Este método se invocará cuando alguna capa superior a ésta detecte un problema tan grave
197 * como para parar la aplicación de forma súbita.
198 * \param className Nombre de la clase que genera el evento.
200 * \warning En el momento de invocar a este método la aplicación puede estar en un estado
201 * no muy estable por lo que se deberían minizar las operaciones a realizar para evitar
202 * bloquear la aplicación.
204 virtual void eventAbnormalTermination(const char* className) throw() { ; }
207 Devuelve una cadena con la informacion referente a esta instancia.
208 \param parent Nodo XML del que dependende la informacion.
209 @return Una cadena con la informacion referente a esta instancia.
211 virtual xml::Node* asXML(xml::Node* parent) const throw();
214 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
215 \param ii Iterator que deberia estar comprendido entre #begin y #end.
216 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
218 static const Component* component(const_iterator& ii) throw() { return *ii; }
221 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
222 \param ii Iterator que deberia estar comprendido entre #begin y #end.
223 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
225 static Component* component(iterator& ii) throw() { return *ii; }
228 static Application* st_application;
231 metodo que debemos implementar para ejecutar nuestra aplicacion.
233 virtual void run() throw(RuntimeException) = 0;
236 Metodo manejador que podemos re-escribir para tratar la recepcion de la senhal USR1.
239 virtual void signalUSR1() throw(RuntimeException);
242 Metodo manejador que podemos re-escribir para tratar la recepcion de la senhal SIGTERM.
244 virtual void signalTerminate() throw(RuntimeException) {;}
247 * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
248 * esta aplicacion desde el punto de vista del proceso original.
249 * \warning Si se detecta algun error terminara abortara la ejecucion del proceso hijo.
251 virtual void do_cloneParent() throw(RuntimeException) {;}
254 * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
255 * esta aplicacion desde el punto de vista del proceso hijo.
256 * \warning Si se detecta algun error terminara abortara la ejecucion de este proceso.
258 virtual void do_cloneChild() throw(RuntimeException) {;}
261 Devuelve un iterador al primer proceso hijo creado por la aplicacion (ver #clone),
262 \return un iterador al primer proceso hijo definido en la aplicacion.
264 pid_iterator pid_begin() throw() { return a_pids.begin(); }
267 Devuelve un iterador al final de lista lista de procesos hijos creados por la aplicacion (ver #clone).
268 \return un iterador al primer proceso hijo definido en la aplicacion.
270 pid_iterator pid_end() throw() { return a_pids.end(); }
273 * Devuelve el numero de procesos hijos.
274 * \return el numero de procesos hijos.
276 int pid_size() const throw() { return a_pids.size(); }
279 Devuelve un iterador al primer proceso hijo creado por la aplicacion (ver #clone),
280 \return un iterador al primer proceso hijo definido en la aplicacion.
282 const_pid_iterator pid_begin() const throw() { return a_pids.begin(); }
285 Devuelve un iterador al final de lista lista de procesos hijos creados por la aplicacion (ver #clone).
286 \return un iterador al primer proceso hijo definido en la aplicacion.
288 const_pid_iterator pid_end() const throw() { return a_pids.end(); }
291 Devuelve el PID sobre el que esta posicionado el iterator recibido como parametro.
292 \param ii Iterator que deberia estar comprendido entre #pid_begin y #pid_end.
293 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
295 static pid_t pid(pid_iterator& ii) throw() { return *ii; }
298 Devuelve el PID sobre el que esta posicionado el iterator recibido como parametro.
299 \param ii Iterator que deberia estar comprendido entre #pid_begin y #pid_end.
300 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
302 static pid_t pid(const_pid_iterator& ii) throw() { return *ii; }
306 std::string a_version;
307 const std::string a_title;
308 std::vector <Component*> a_components;
310 const char* a_shortName;
312 pid_container a_pids;
314 void attach(Component*) throw(RuntimeException);
315 void detach(Component*) throw(RuntimeException);
317 void startComponents() throw(RuntimeException);
318 void stopComponents() throw(RuntimeException);
319 void sendSignalToChilds(const int signal) throw();
321 static void handlerSignalUSR1(int) throw();
322 static void handlerSignalTerminate(int) throw();
323 static void handlerChildTerminate(int sig) throw();
325 friend class Component; // Para poder acceder a los metodo attach y detach
326 friend struct functions;