First commit
[anna.git] / include / anna / app / Component.hpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
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
16 // distribution.
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.
20 //
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.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 #ifndef anna_app_Component_hpp
38 #define anna_app_Component_hpp
39
40 #include <vector>
41
42 #include <anna/core/RuntimeException.hpp>
43 #include <anna/core/mt/Mutex.hpp>
44
45 #include <anna/app/Application.hpp>
46
47 namespace anna {
48
49 namespace xml {
50 class Node;
51 }
52
53 namespace app {
54
55 /**
56    Clase de la que heredan los componentes de aplicacion.
57
58    Solo deberia haber una instancia de cada uno de los componentes, pero no podemos
59    declararlos como heredados de anna::Singleton porque debemos dar la posiblidad de
60    que el programador re-escriba su comportamiento mediante herencia.
61
62    Todos los componentes se arrancan y paran automaticamente desde la aplicacion.
63
64    El siguiente ejemplo muestra como obtener la instancia de un componente asociado a nuestra aplicacion:
65
66    \code
67       Clase* objeto = anna::app::functions::component <Clase> (FILE_LOCATION);
68
69       ..... uso del objeto ....
70    \endcode
71
72    Si el componente \em 'Clase' no hubiera sido registrado (instanciado) en nuestra aplicacion el metodo
73    template anna::component lanzara una excepcion.
74 */
75 class Component : public Mutex {
76 public:
77   /**
78      Destructor.
79   */
80   virtual ~Component();
81
82   /**
83      Devuelve el nombre de esta clase indicado en el constructor.
84      \return El nombre de la clase indicado en el constructor.
85   */
86   const char* getClassName() const throw() { return a_className.c_str(); }
87
88   /**
89      Conecta explicitamente este componente con la aplicacion. Sera necesario invocar a este metodo
90      cuando instanciemos un componentes despues de comenzar la ejecucion de nuestra aplicacion y
91      cuando el nuevo componente este completamente listo para su inicializacion.
92   */
93   void attach() throw(RuntimeException);
94
95   /**
96      Devuelve una cadena con la informacion mas relevante de esta instancia.
97      \return Una cadena con la informacion mas relevante de esta instancia.
98   */
99   virtual std::string asString() const throw();
100
101   /**
102      Devuelve un documento XML con la informacion mas relevante de esta instancia.
103      \param parent Nodo XML del que colgar la informacion referente a esta instancia.
104      \return Un documento XML con la informacion mas relevante de esta instancia.
105   */
106   virtual xml::Node* asXML(xml::Node* parent) const throw();
107
108 protected:
109   /**
110      Estados en los que puede estar un componente.
111      \see Component.
112   */
113   struct State { enum _v { Stopped, Starting, Running }; };
114
115   /**
116      Contructor.
117      @param className Nombre lgico asociado a esta clase.
118   */
119   explicit Component(const char* className);
120
121   /**
122      Devuelve el estado de este componente.
123      \return el estado de este componente.
124   */
125   State::_v getState() const throw() { return a_state; }
126
127   /**
128      Indica que el nombre de un componente que debe ser initializa antes que este.
129      \param componentName Nombre de componente requerido por esta instancia.
130      \warning Solo tendra efecto antes de inicializar el componente.
131   */
132   void addPredecessor(const char* componentName) throw();
133
134   /**
135      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
136      Este metodo se invocara automaticamente desde anna::Application::start.
137   */
138   void initialize() throw(RuntimeException);
139
140   /**
141      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
142      esta clase.
143
144      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
145      desde el nucleo
146   */
147   void stop() throw() { a_state = State::Stopped; do_stop(); }
148
149   /**
150      metodo que debemos implementar en la clase heredada para implementar el proceso de parada de
151      esta clase. Se invocara automaticamente desde el nucleo
152
153      Este metodo implementa un metodo de parada no controlada.
154   */
155   virtual void kill() throw() { stop(); }
156
157 private:
158   typedef std::vector <std::string>::iterator iterator;
159
160   const std::string a_className;
161   State::_v a_state;
162   std::vector <std::string> a_predecessors;
163
164   Component(const Component& other);
165   iterator begin() throw() { return a_predecessors.begin(); }
166   iterator end() throw() { return a_predecessors.end(); }
167   const std::string& data(iterator& ii) throw() { return *ii; }
168
169   /**
170      metodo que debemos implementar si la clase heredada necesita algn tipo de inicializacin.
171      Este metodo se invocara automaticamente desde anna::Application::start.
172   */
173   virtual void do_initialize() throw(RuntimeException) = 0;
174
175   /**
176      Metodo que debemos implementar en la clase heredada para tratar el proceso de parada de
177      esta clase.
178      Este metodo debe implementar un metodo de parada controlada. Se invocara automaticamente
179      desde el nucleo
180   */
181   virtual void do_stop() throw() = 0;
182
183   /**
184    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
185    * esta clase desde el punto de vista del proceso original.
186    * \warning Si se detecta algun error terminara abortara la ejecucion del proceso hijo.
187    */
188   virtual void do_cloneParent() throw(RuntimeException) { ; }
189
190   /**
191    * Metodo que debemos implementar en la clase heredada para tratar el proceso de clonado de
192    * esta clase desde el punto de vista del proceso hijo.
193    * \warning Si se detecta algun error terminara abortara la ejecucion de este proceso.
194    */
195   virtual void do_cloneChild() throw(RuntimeException) { ; }
196
197   friend void Application::startComponents() throw(RuntimeException);
198   friend void Application::stopComponents() throw(RuntimeException);
199   friend void Application::attach(Component*) throw(RuntimeException);
200   friend Application& Application::clone() throw(RuntimeException);
201 };
202
203 }
204 }
205
206 #endif