First commit
[anna.git] / include / anna / xml / Parser.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_xml_Parser_hpp
38 #define anna_xml_Parser_hpp
39
40 #include <anna/core/RuntimeException.hpp>
41 #include <anna/core/mt/Mutex.hpp>
42
43 struct _xmlValidCtxt;
44 struct _xmlDoc;
45 struct _xmlNode;
46 struct _xmlAttr;
47
48 namespace anna {
49
50 class DataBlock;
51
52 namespace xml {
53
54 class Node;
55 class DTD;
56 class Document;
57 class Attribute;
58
59 /**
60    Analizador de documentos XML.
61
62    Analiza la expresion contenida en un documento XML, opcionalmente puede validar la estructura
63    mediante una DTD suministrada a tal efecto, y devuelve un arbol de nodos que resulta muy
64    facil de usar.
65
66    Ejemplo de documento XML:
67
68    \code
69
70    <xvc HeartBeat="20000">
71       <broadcast>
72          <INetAddress Address="204.152.65.15" Port="2000"/>
73          <INetAddress Address="204.152.65.47" Port="2002"/>
74       </broadcast>
75
76       <ethernet Mode="raw" VirtualAddress="1.1.1.100">
77          <Input Device="/dev/qfe" PhysicalAccessPoint="2" MAC="8:0:20:9e:ee:21"/>
78          <Output Device="/dev/qfe" PhysicalAccessPoint="2" MAC="8:0:20:9e:ee:c9"/>
79       </ethernet>
80    </xvc>
81
82    \endcode
83
84    Donde los nodos (Ver \ref Node) \em broadcast y \em ethernet son hijos del nodo \em xvc. De la misma forma
85    los nodos \em Input y \em Output son hijos de \em ethernet.
86
87    Cada nodo XML puede tener una serie indeterminada de atributos (Ver \ref Attribute) que completan su
88    significado. Por ejemplo \em Device, \em PhysicalAccessPoint y \em MAC son atributos de los nodos \em Input y
89    \em Output.
90 */
91 class Parser : public Mutex {
92 public:
93   /**
94      Constructor.
95   */
96   Parser();
97
98   /**
99      Destructor.
100   */
101   virtual ~Parser();
102
103   /**
104      Devuelve el nodo raiz de la expresion XML analizada. Puede ser NULL.
105
106      \return El nodo raiz de la expresion XML analizada. Puede ser NULL.
107      \warning
108         \li El resultado de este metodo solo sera valido despues de invocar a alguno
109      de los metodo #apply.
110         \li El nodo devuelto  no puede ser usado despues del invocar a destructor de este Parser.
111   */
112   const Node* getRoot() const throw() { return a_root; }
113
114   /**
115      Analiza el documento XML recibido como parametro.
116      \param document Documento XML que deseamos analizar.
117      \return El nodo raiz del arbol XML correspondiente al documento analizado.
118      \warning
119         \li La instancia del documento debe estar correctamente inicializada.
120         \li El nodo devuelto  no puede ser usado despues del invocar a destructor de este Parser.
121      \see Document::initialize
122   */
123   const Node* apply(const Document& document) throw(RuntimeException);
124
125   /**
126      Analiza el archivo XML recibido como parametro, y verifica que cumpla las reglas
127      establecidas por la DTD.
128      \param document Documento XML que deseamos analizar.
129      \param dtd DTD que debe cumplir el documento XML.
130      \return El nodo raiz del arbol XML correspondiente al resultado del analisis.
131
132      \warning
133         \li La instancia de la DTD y el documento deben estar correctamente inicializadas.
134         \li El nodo devuelto  no puede ser usado despues del invocar a destructor de este Parser.
135
136      \see DTD::initialize
137      \see Document::initialize
138   */
139   const Node* apply(const Document& document, const DTD& dtd) throw(RuntimeException);
140
141 protected:
142   /*
143    * Nodo ráiz del árbol representado por el documento XML analizado.
144    */
145   Node* a_root;
146
147   /**
148      Inicializa el contenido del nodo asociado al ultimo Parser::apply.
149      \warning Se invoca automaticamente desde el numero de ANNA.xml
150   */
151   virtual void reset() throw();
152
153   /**
154    * Comprueba si se requieren operaciones de traducción del conjunto de caracteres.
155    */
156   void setupEncoding(_xmlDoc* document) throw();
157
158   /**
159    * Si fuera necesario traduce el texto contenido por el parámetro recibido al conjunto
160    * de caracteres indicado por el documento XML que estamos tratando.
161    * \param source Texto expresado en el conjunto de caracteres particular.
162    * \return Una cadena expresada en UTF-8.
163    */
164   const char* decode(const unsigned char* source) throw();
165
166   /**
167    * \warning Exclusivamente uso interno.
168    */
169   void attributes(Node* node, _xmlAttr* attribute) throw(RuntimeException);
170
171   /**
172    * \warning Exclusivamente uso interno.
173    */
174   void children(Node* node, _xmlNode* xmlNode) throw(RuntimeException);
175
176 private:
177   _xmlValidCtxt* a_context;
178   static char st_text [1024];
179   static anna::RuntimeException* st_exception;
180   bool a_encoding;
181   DataBlock* a_buffEncode;
182
183   Parser(const Parser&);
184
185   void apply(_xmlDoc* document) throw(RuntimeException);
186
187   static void errorHandler(void *ctx,  const char *msg, ...) throw();
188   static void warningHandler(void *ctx,  const char *msg, ...) throw();
189 };
190
191 }
192 }
193
194 #endif