bug in RC
[anna.git] / include / anna / app / Application.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_app_Application_hpp
10 #define anna_app_Application_hpp
11
12 #include <vector>
13
14 #include <anna/core/RuntimeException.hpp>
15
16 namespace anna {
17
18 namespace xml {
19 class Node;
20 }
21
22 namespace app {
23
24 class Component;
25 struct functions;
26
27 /**
28    Application abstraction.
29
30    Gather all the information of resources (version, title, command line,
31    threads, etc ...) used by our applications.
32
33    Only one single instance could exists for the application, accessed by mean anna::functions::getApp.
34 */
35 class Application {
36 public:
37   typedef std::vector <Component*>::iterator iterator;
38   typedef std::vector <Component*>::const_iterator const_iterator;
39   typedef std::vector <pid_t> pid_container;
40   typedef pid_container::iterator pid_iterator;
41   typedef pid_container::const_iterator const_pid_iterator;
42
43   /**
44      Constructor.
45
46      @param shortName Instance logical name.
47      @param title Application title (appears when the application starts).
48      @param version Program version (recommended X.YRZZn with X = main version, Y = secondary version, ZZ = delivery number
49      \param date Component build date. Normally the macro __DATE__.
50      \param time Component build time. Normally the macro __TIME__.
51   */
52   Application(const char* shortName, const char* title, const char* version, const char* date = NULL, const char* time = NULL);
53
54   /**
55      Destructor.
56   */
57   virtual ~Application() { a_components.clear(); }
58
59   // Getters
60   /**
61      Short name given in constructor.
62      \return Short name given in constructor.
63   */
64   const char* getShortName() const throw() { return a_shortName; }
65
66   /**
67      Version given in constructor.
68      \return Version given in constructor.
69   */
70   const std::string& getVersion() const throw() { return a_version; }
71
72   /**
73      Devuelve el titulo indicado en el contructor de esta aplicacion.
74      \return el titulo indicado en el contructor de esta aplicacion.
75   */
76   const std::string& getTitle() const throw() { return a_title; }
77
78   /**
79      Devuelve el pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
80      @return El pid asignado por el sistema operativo a la aplicacion que estamos ejecutando.
81   */
82   pid_t getPid() const throw() { return a_pid; }
83
84   /**
85      Activa la salida por pantalla del mensaje referente a la licencia GPL 3.0.
86      \warning Para que tenga efecto debe ser invocado antes de ejecutar el metodo Application::start.
87   */
88   void activateGeneralPublicLicense() throw() { a_enableGPL = true; }
89
90   /**
91    * Crea un nuevo proceso a partir de este usando el metodo \em fork.
92    *
93    * Estrictamente este metodo retonara dos veces, una en el ambito del proceso que lo invoco y
94    * otra en el ambito del nuevo proceso, llamado proceso hijo.
95    *
96    * Si la duplicacion se realiza de forma correcta se invoca a los metodos #do_cloneChild y #do_cloneParent de nuestra
97    * aplicacion y Component::do_cloneChild y Component::do_cloneParent de cada uno de los componentes registrados.
98    *
99    * Para saber en cual de los procesos
100    * \return La instancia de la nueva aplicacion.
101    */
102   Application& clone() throw(RuntimeException);
103
104   /**
105      Devuelve la instancia del componente que corresponde con el nombre recibido.
106      \return La instancia del componente que corresponde con el nombre recibido. Puede ser NULL si no
107      hay ningun componente asociado a la �ta aplicacion que corresponda con el nombre.
108   */
109   Component* find(const char* className) throw();
110
111   /**
112      Inicializa los elementos propios de nuestra aplicacio, invoca al metodo #initialize
113      e invoca al metodo #run.
114   */
115   void start() throw(RuntimeException);
116
117   /**
118      Devuelve un iterador al primer componente definido en la aplicacion.
119      \return un iterador al primer componente definido en la aplicacion.
120   */
121   const_iterator begin() const throw() { return a_components.begin(); }
122
123   /**
124      Devuelve un iterador al primer componente definido en la aplicacion.
125      \return un iterador al primer componente definido en la aplicacion.
126   */
127   iterator begin() throw() { return a_components.begin(); }
128
129   /**
130      Devuelve un iterador al ultimo componente definido en la aplicacion.
131      \return un iterador al ultimo componente definido en la aplicacion.
132   */
133   const_iterator end() const throw() { return a_components.end(); }
134
135   /**
136      Devuelve un iterador al ultimo componente definido en la aplicacion.
137      \return un iterador al ultimo componente definido en la aplicacion.
138   */
139   iterator end() throw() { return a_components.end(); }
140
141   /**
142      Vuelva un documento XML con el contexto de la aplicacion.
143      \param file Ruta completa del fichero en el que grabar el contexto de la aplicacion.
144   */
145   void writeContext(const std::string& file) throw(RuntimeException);
146
147   /**
148      metodo que puede ser reescrito en las clases heredadas de Application y que nos
149      da la posibilidad de inicializar los elementos particulares de nuestra aplicacion.
150      Por defecto no realiza ninguna operacion.
151      \warning En el momento de invocar a esta funcin los componentes (\see Component) pueden no
152      estar disponibles.
153   */
154   virtual void initialize() throw(RuntimeException) {;}
155
156   /**
157      Devuelve si esta aplicacion tiene soporto para comunicaciones entre procesos.
158      \return \em true si la aplicacion tiene soporta para comunicacion entre proceso o \em false
159      en otro caso.
160   */
161   virtual bool supportCommunication() const throw() { return false; }
162
163   /**
164    * Este m�todo se invocar� cuando alguna capa superior a �sta detecte un problema tan grave
165    * como para parar la aplicaci�n de forma s�bita.
166    * \param className Nombre de la clase que genera el evento.
167    *
168    * \warning En el momento de invocar a este m�todo la aplicaci�n puede estar en un estado
169    * no muy estable por lo que se deber�an minizar las operaciones a realizar para evitar
170    * bloquear la aplicaci�n.
171    */
172   virtual void eventAbnormalTermination(const char* className) throw() { ; }
173
174   /**
175      Devuelve una cadena con la informacion referente a esta instancia.
176      \param parent Nodo XML del que dependende la informacion.
177      @return Una cadena con la informacion referente a esta instancia.
178   */
179   virtual xml::Node* asXML(xml::Node* parent) const throw();
180
181   /**
182      Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
183      \param ii Iterator que deberia estar comprendido entre #begin y #end.
184      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
185   */
186   static const Component* component(const_iterator& ii) throw() { return *ii; }
187
188   /**
189      Devuelve el objeto sobre el que esta posicionado el iterator recibido como parametro.
190      \param ii Iterator que deberia estar comprendido entre #begin y #end.
191      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
192   */
193   static Component* component(iterator& ii) throw() { return *ii; }
194
195 protected:
196   static Application* st_application;
197
198   /**
199      metodo que debemos implementar para ejecutar nuestra aplicacion.
200   */
201   virtual void run() throw(RuntimeException) = 0;
202
203   /**
204      Handler for SIGUSR1. Application context written by default.
205   */
206   virtual void signalUSR1() throw(RuntimeException);
207
208   /**
209      Handler for SIGUSR2. Nothing done by default.
210   */
211   virtual void signalUSR2() throw(RuntimeException);
212
213   /**
214      Metodo manejador que podemos re-escribir para tratar la recepcion de la senhal SIGTERM.
215   */
216   virtual void signalTerminate() throw(RuntimeException) {;}
217
218   /**
219    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
220    * esta aplicacion desde el punto de vista del proceso original.
221    * \warning Si se detecta algun error terminara abortara la ejecucion del proceso hijo.
222    */
223   virtual void do_cloneParent() throw(RuntimeException) {;}
224
225   /**
226    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
227    * esta aplicacion desde el punto de vista del proceso hijo.
228    * \warning Si se detecta algun error terminara abortara la ejecucion de este proceso.
229    */
230   virtual void do_cloneChild() throw(RuntimeException) {;}
231
232   /**
233      Devuelve un iterador al primer proceso hijo creado por la aplicacion (ver #clone),
234      \return un iterador al primer proceso hijo definido en la aplicacion.
235   */
236   pid_iterator pid_begin() throw() { return a_pids.begin(); }
237
238   /**
239      Devuelve un iterador al final de lista lista de procesos hijos creados por la aplicacion (ver #clone).
240      \return un iterador al primer proceso hijo definido en la aplicacion.
241   */
242   pid_iterator pid_end() throw() { return a_pids.end(); }
243
244   /**
245    * Devuelve el numero de procesos hijos.
246    * \return el numero de procesos hijos.
247    */
248   int pid_size() const throw() { return a_pids.size(); }
249
250   /**
251      Devuelve un iterador al primer proceso hijo creado por la aplicacion (ver #clone),
252      \return un iterador al primer proceso hijo definido en la aplicacion.
253   */
254   const_pid_iterator pid_begin() const throw() { return a_pids.begin(); }
255
256   /**
257      Devuelve un iterador al final de lista lista de procesos hijos creados por la aplicacion (ver #clone).
258      \return un iterador al primer proceso hijo definido en la aplicacion.
259   */
260   const_pid_iterator pid_end() const throw() { return a_pids.end(); }
261
262   /**
263      Devuelve el PID sobre el que esta posicionado el iterator recibido como parametro.
264      \param ii Iterator que deberia estar comprendido entre #pid_begin y #pid_end.
265      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
266   */
267   static pid_t pid(pid_iterator& ii) throw() { return *ii; }
268
269   /**
270      Devuelve el PID sobre el que esta posicionado el iterator recibido como parametro.
271      \param ii Iterator que deberia estar comprendido entre #pid_begin y #pid_end.
272      \return El objeto sobre el que esta posicionado el iterator recibido como parametro.
273   */
274   static pid_t pid(const_pid_iterator& ii) throw() { return *ii; }
275
276 private:
277   bool a_running;
278   std::string a_version;
279   const std::string a_title;
280   std::vector <Component*> a_components;
281   pid_t a_pid;
282   const char* a_shortName;
283   bool a_enableGPL;
284   pid_container a_pids;
285
286   void attach(Component*) throw(RuntimeException);
287   void detach(Component*) throw(RuntimeException);
288
289   void startComponents() throw(RuntimeException);
290   void stopComponents() throw(RuntimeException);
291   void sendSignalToChilds(const int signal) throw();
292
293   void signalUSR(int) throw(RuntimeException);
294   static void handlerSignalUSR(int) throw();
295   static void handlerSignalTerminate(int) throw();
296   static void handlerChildTerminate(int sig) throw();
297
298   friend class Component;  // Para poder acceder a los metodo attach y detach
299   friend struct functions;
300 };
301
302 }
303 }
304
305 #endif
306