Changed LICENSE. Now referenced to web site and file on project root directory
[anna.git] / include / anna / app / Component.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_Component_hpp
10 #define anna_app_Component_hpp
11
12 #include <vector>
13
14 #include <anna/core/RuntimeException.hpp>
15 #include <anna/core/mt/Mutex.hpp>
16
17 #include <anna/app/Application.hpp>
18
19 namespace anna {
20
21 namespace xml {
22 class Node;
23 }
24
25 namespace app {
26
27 /**
28    Clase de la que heredan los componentes de aplicacion.
29
30    Solo deberia haber una instancia de cada uno de los componentes, pero no podemos
31    declararlos como heredados de anna::Singleton porque debemos dar la posiblidad de
32    que el programador re-escriba su comportamiento mediante herencia.
33
34    Todos los componentes se arrancan y paran automaticamente desde la aplicacion.
35
36    El siguiente ejemplo muestra como obtener la instancia de un componente asociado a nuestra aplicacion:
37
38    \code
39       Clase* objeto = anna::app::functions::component <Clase> (FILE_LOCATION);
40
41       ..... uso del objeto ....
42    \endcode
43
44    Si el componente \em 'Clase' no hubiera sido registrado (instanciado) en nuestra aplicacion el metodo
45    template anna::component lanzara una excepcion.
46 */
47 class Component : public Mutex {
48 public:
49   /**
50      Destructor.
51   */
52   virtual ~Component();
53
54   /**
55      Class name given in constructor.
56      \return El nombre de la clase indicado en el constructor.
57   */
58   const char* getClassName() const throw() { return a_className.c_str(); }
59
60   /**
61      Conecta explicitamente este componente con la aplicacion. Sera necesario invocar a este metodo
62      cuando instanciemos un componentes despues de comenzar la ejecucion de nuestra aplicacion y
63      cuando el nuevo componente este completamente listo para su inicializacion.
64   */
65   void attach() throw(RuntimeException);
66
67   /**
68      Devuelve una cadena con la informacion mas relevante de esta instancia.
69      \return Una cadena con la informacion mas relevante de esta instancia.
70   */
71   virtual std::string asString() const throw();
72
73   /**
74      Devuelve un documento XML con la informacion mas relevante de esta instancia.
75      \param parent Nodo XML del que colgar la informacion referente a esta instancia.
76      \return Un documento XML con la informacion mas relevante de esta instancia.
77   */
78   virtual xml::Node* asXML(xml::Node* parent) const throw();
79
80 protected:
81   /**
82      Estados en los que puede estar un componente.
83      \see Component.
84   */
85   struct State { enum _v { Stopped, Starting, Running }; };
86
87   /**
88      Contructor.
89      @param className Nombre lgico asociado a esta clase.
90   */
91   explicit Component(const char* className);
92
93   /**
94      Devuelve el estado de este componente.
95      \return el estado de este componente.
96   */
97   State::_v getState() const throw() { return a_state; }
98
99   /**
100      Indica que el nombre de un componente que debe ser initializa antes que este.
101      \param componentName Nombre de componente requerido por esta instancia.
102      \warning Solo tendra efecto antes de inicializar el componente.
103   */
104   void addPredecessor(const char* componentName) throw();
105
106   /**
107      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
108      Este metodo se invocara automaticamente desde anna::Application::start.
109   */
110   void initialize() throw(RuntimeException);
111
112   /**
113      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
114      esta clase.
115
116      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
117      desde el nucleo
118   */
119   void stop() throw() { a_state = State::Stopped; do_stop(); }
120
121   /**
122      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
123      esta clase. Se invocara automaticamente desde el nucleo
124
125      Este metodo implementa un metodo de parada no controlada.
126   */
127   virtual void kill() throw() { stop(); }
128
129 private:
130   typedef std::vector <std::string>::iterator iterator;
131
132   const std::string a_className;
133   State::_v a_state;
134   std::vector <std::string> a_predecessors;
135
136   Component(const Component& other);
137   iterator begin() throw() { return a_predecessors.begin(); }
138   iterator end() throw() { return a_predecessors.end(); }
139   const std::string& data(iterator& ii) throw() { return *ii; }
140
141   /**
142      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
143      Este metodo se invocara automaticamente desde anna::Application::start.
144   */
145   virtual void do_initialize() throw(RuntimeException) = 0;
146
147   /**
148      Metodo que debemos implementar en la clase heredada para tratar el proceso de parada de
149      esta clase.
150      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
151      desde el nucleo
152   */
153   virtual void do_stop() throw() = 0;
154
155   /**
156    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
157    * esta clase desde el punto de vista del proceso original.
158    * \warning Si se detecta algun error terminara abortara la ejecucion del proceso hijo.
159    */
160   virtual void do_cloneParent() throw(RuntimeException) { ; }
161
162   /**
163    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
164    * esta clase desde el punto de vista del proceso hijo.
165    * \warning Si se detecta algun error terminara abortara la ejecucion de este proceso.
166    */
167   virtual void do_cloneChild() throw(RuntimeException) { ; }
168
169   friend void Application::startComponents() throw(RuntimeException);
170   friend void Application::stopComponents() throw(RuntimeException);
171   friend void Application::attach(Component*) throw(RuntimeException);
172   friend Application& Application::clone() throw(RuntimeException);
173 };
174
175 }
176 }
177
178 #endif