1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
9 #include <anna/core/functions.hpp>
11 #include <anna/xml/Node.hpp>
12 #include <anna/xml/Attribute.hpp>
13 #include <anna/xml/Text.hpp>
17 using namespace anna::xml;
20 * Si el nodo no tiene padre => debe crear los pool de datos en los que sus descendientes irán
21 * creando los objetos que vayan siendo necesarios.
23 * Éste es el constructor que se usará para instanciar al nodo ROOT.
25 Node::Node(const char* name) : a_name(name), a_parent(NULL), a_text(NULL), a_namespace(NULL) {
26 a_node_pool = new node_pool;
27 a_attribute_pool = new attribute_pool;
28 a_text_pool = new text_pool;
29 a_namespace_pool = new namespace_pool;
30 a_namespaces = new namespace_container;
35 * Si el nodo tiene padre => copiará las instancias de los pools de datos.
37 Node::Node() : a_parent(NULL), a_text(NULL), a_namespace(NULL) {
39 a_attribute_pool = NULL;
41 a_namespace_pool = NULL;
49 if(a_parent == NULL) {
51 delete a_attribute_pool;
53 delete a_namespace_pool;
60 for(attribute_iterator aa = a_attributes.begin(), maxaa = a_attributes.end(); aa != maxaa; aa ++)
61 a_attribute_pool->release(attribute(aa));
65 for(Children::iterator cc = a_children.begin(), maxcc = a_children.end(); cc != maxcc; cc ++) {
68 a_node_pool->release(aux);
74 a_text_pool->release(a_text);
78 // Si es el nodo root ....
79 if(a_parent == NULL) {
80 a_namespaces->clear();
81 a_namespace_pool->clear();
87 const Attribute* Node::getAttribute(const char* name, const bool exceptionWhenNotFound) const
88 throw(RuntimeException) {
89 const Attribute* result(NULL);
90 result = find(name, attribute_begin(), attribute_end());
92 if(result == NULL && exceptionWhenNotFound == true) {
93 string msg = asString();
94 msg += " | Attribute: ";
96 msg += " | Not found";
97 throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
103 xml::Attribute* Node::createAttribute(const char* name, const char* value, const Namespace* _namespace)
105 Attribute* attribute = a_attribute_pool->create();
106 attribute->setNode(this);
107 attribute->setName(name);
108 attribute->setValue(value);
109 attribute->setNamespace(_namespace);
110 a_attributes.push_back(attribute);
114 xml::Text* Node::createText(const char* text)
115 throw(RuntimeException) {
117 string msg = asString();
119 msg += a_text->asString();
120 msg += " | Node has already text assigned";
121 throw RuntimeException(msg, ANNA_FILE_LOCATION);
124 a_text = a_text_pool->create();
125 a_text->setNode(this);
126 a_text->setValue(text);
130 Node* Node::createChild(const char* name)
132 Node* result = a_node_pool->create();
133 result->a_parent = this;
134 result->setName(name);
135 result->a_node_pool = a_node_pool;
136 result->a_attribute_pool = a_attribute_pool;
137 result->a_text_pool = a_text_pool;
138 result->a_root = a_root;
139 a_children.push_back(result);
144 * Recordar que todos los namespaces se crean sólo en el nodo ROOT.
146 const Namespace* Node::createNamespace(const std::string& name, const char* reference)
147 throw(RuntimeException) {
148 const Namespace* result = NULL;
150 if((result = namespace_find(name, false)) != NULL) {
151 if(result->getReference() != reference) {
152 string msg(result->asString());
153 msg += " | New reference: ";
155 msg += " | Namespace already defined";
156 throw RuntimeException(msg, ANNA_FILE_LOCATION);
160 Namespace* newns = a_namespace_pool->create();
161 newns->setName(name);
162 newns->setReference(reference);
163 a_namespaces->add(newns);
166 result = a_root->createNamespace(name, reference);
172 const Node* Node::find(const char* childName, const bool exceptionWhenNotFound) const
173 throw(RuntimeException) {
176 for(Node::Children::const_iterator ii = a_children.begin(), maxii = a_children.end(); ii != maxii; ii ++) {
179 if(anna_strcmp(child->a_name.c_str(), childName) == 0)
183 if(exceptionWhenNotFound == true) {
184 std::string msg("Successor '");
186 msg += "' not found at node '";
189 throw RuntimeException(msg, ANNA_FILE_LOCATION);
195 Namespace* Node::namespace_find(const std::string& name, const bool exceptionWhenNotFound)
196 throw(RuntimeException) {
197 Namespace* result = a_root->a_namespaces->find(name);
199 if(result == NULL && exceptionWhenNotFound == true) {
200 string msg(asString());
201 msg += " | Namespace: ";
203 msg += " | Namespace is not defined";
204 throw RuntimeException(msg, ANNA_FILE_LOCATION);
210 string Node::asString() const
212 string result("xml::Node { Name: ");
215 if(a_namespace != NULL) {
217 result += a_namespace->asString();
220 return result += " }";
223 const Attribute* Node::find(const char* attrName, const_attribute_iterator begin, const_attribute_iterator end)
225 Attribute* attribute;
227 for(; begin != end; begin ++) {
230 if(anna_strcmp(attribute->getName(), attrName) == 0)