1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
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 the copyright holder 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>
56 Application abstraction.
58 Gather all the information of resources (version, title, command line,
59 threads, etc ...) used by our applications.
61 Only one single instance could exists for the application, accessed by mean anna::functions::getApp.
65 typedef std::vector <Component*>::iterator iterator;
66 typedef std::vector <Component*>::const_iterator const_iterator;
67 typedef std::vector <pid_t> pid_container;
68 typedef pid_container::iterator pid_iterator;
69 typedef pid_container::const_iterator const_pid_iterator;
74 @param shortName Instance logical name.
75 @param title Application title (appears when the application starts).
76 @param version Program version (recommended X.YRZZn with X = main version, Y = secondary version, ZZ = delivery number
77 \param date Component build date. Normally the macro __DATE__.
78 \param time Component build time. Normally the macro __TIME__.
80 Application(const char* shortName, const char* title, const char* version, const char* date = NULL, const char* time = NULL);
85 virtual ~Application() { a_components.clear(); }
89 Short name given in constructor.
90 \return Short name given in constructor.
92 const char* getShortName() const throw() { return a_shortName; }
95 Version given in constructor.
96 \return Version given in constructor.
98 const std::string& getVersion() const throw() { return a_version; }
101 Devuelve el titulo indicado en el contructor de esta aplicacion.
102 \return el titulo indicado en el contructor de esta aplicacion.
104 const std::string& getTitle() const throw() { return a_title; }
107 Devuelve el pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
108 @return El pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
110 pid_t getPid() const throw() { return a_pid; }
113 Activa la salida por pantalla del mensaje referente a la licencia GPL 3.0.
114 \warning Para que tenga efecto debe ser invocado antes de ejecutar el metodo Application::start.
116 void activateGeneralPublicLicense() throw() { a_enableGPL = true; }
119 * Crea un nuevo proceso a partir de este usando el metodo \em fork.
121 * Estrictamente este metodo retonara dos veces, una en el ambito del proceso que lo invoco y
122 * otra en el ambito del nuevo proceso, llamado proceso hijo.
124 * Si la duplicacion se realiza de forma correcta se invoca a los metodos #do_cloneChild y #do_cloneParent de nuestra
125 * aplicacion y Component::do_cloneChild y Component::do_cloneParent de cada uno de los componentes registrados.
127 * Para saber en cual de los procesos
128 * \return La instancia de la nueva aplicacion.
130 Application& clone() throw(RuntimeException);
133 Devuelve la instancia del componente que corresponde con el nombre recibido.
134 \return La instancia del componente que corresponde con el nombre recibido. Puede ser NULL si no
135 hay ningun componente asociado a la �ta aplicacion que corresponda con el nombre.
137 Component* find(const char* className) throw();
140 Inicializa los elementos propios de nuestra aplicacio, invoca al metodo #initialize
141 e invoca al metodo #run.
143 void start() throw(RuntimeException);
146 Devuelve un iterador al primer componente definido en la aplicacion.
147 \return un iterador al primer componente definido en la aplicacion.
149 const_iterator begin() const throw() { return a_components.begin(); }
152 Devuelve un iterador al primer componente definido en la aplicacion.
153 \return un iterador al primer componente definido en la aplicacion.
155 iterator begin() throw() { return a_components.begin(); }
158 Devuelve un iterador al ultimo componente definido en la aplicacion.
159 \return un iterador al ultimo componente definido en la aplicacion.
161 const_iterator end() const throw() { return a_components.end(); }
164 Devuelve un iterador al ultimo componente definido en la aplicacion.
165 \return un iterador al ultimo componente definido en la aplicacion.
167 iterator end() throw() { return a_components.end(); }
170 Vuelva un documento XML con el contexto de la aplicacion.
171 \param file Ruta completa del fichero en el que grabar el contexto de la aplicacion.
173 void writeContext(const std::string& file) throw(RuntimeException);
176 metodo que puede ser reescrito en las clases heredadas de Application y que nos
177 da la posibilidad de inicializar los elementos particulares de nuestra aplicacion.
178 Por defecto no realiza ninguna operacion.
179 \warning En el momento de invocar a esta funcin los componentes (\see Component) pueden no
182 virtual void initialize() throw(RuntimeException) {;}
185 Devuelve si esta aplicacion tiene soporto para comunicaciones entre procesos.
186 \return \em true si la aplicacion tiene soporta para comunicacion entre proceso o \em false
189 virtual bool supportCommunication() const throw() { return false; }
192 * Este m�todo se invocar� cuando alguna capa superior a �sta detecte un problema tan grave
193 * como para parar la aplicaci�n de forma s�bita.
194 * \param className Nombre de la clase que genera el evento.
196 * \warning En el momento de invocar a este m�todo la aplicaci�n puede estar en un estado
197 * no muy estable por lo que se deber�an minizar las operaciones a realizar para evitar
198 * bloquear la aplicaci�n.
200 virtual void eventAbnormalTermination(const char* className) throw() { ; }
203 Devuelve una cadena con la informacion referente a esta instancia.
204 \param parent Nodo XML del que dependende la informacion.
205 @return Una cadena con la informacion referente a esta instancia.
207 virtual xml::Node* asXML(xml::Node* parent) const throw();
210 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
211 \param ii Iterator que deberia estar comprendido entre #begin y #end.
212 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
214 static const Component* component(const_iterator& ii) throw() { return *ii; }
217 Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
218 \param ii Iterator que deberia estar comprendido entre #begin y #end.
219 \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
221 static Component* component(iterator& ii) throw() { return *ii; }
224 static Application* st_application;
227 metodo que debemos implementar para ejecutar nuestra aplicacion.
229 virtual void run() throw(RuntimeException) = 0;
232 Handler for SIGUSR1. Application context written by default.
234 virtual void signalUSR1() throw(RuntimeException);
237 Handler for SIGUSR2. Nothing done by default.
239 virtual void signalUSR2() 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 void signalUSR(int) throw(RuntimeException);
322 static void handlerSignalUSR(int) throw();
323 static void handlerSignalTerminate(int) throw();
324 static void handlerChildTerminate(int sig) throw();
326 friend class Component; // Para poder acceder a los metodo attach y detach
327 friend struct functions;