[source-changes] r594 - grazer lib ncore/xml shell shell/xml
takada at zebra.org
takada at zebra.org
Thu Aug 31 16:15:35 PDT 2006
Author: takada
Date: 2006-08-31 16:15:32 -0700 (Thu, 31 Aug 2006)
New Revision: 594
Added:
grazer/grazer_config.cpp
grazer/grazer_config.hpp
Modified:
grazer/Makefile.am
grazer/grazer.cpp
grazer/grazer.hpp
grazer/grazer_show.cpp
lib/http.hpp
lib/schema.cpp
lib/schema.hpp
ncore/xml/ip-route.xsd
shell/command.cpp
shell/xml/bgp.xsd
shell/xml/config.xsd
shell/xml/exec.xsd
shell/xml/rip.xsd
Log:
Introduce new framework for grazer DB.
Modified: grazer/Makefile.am
===================================================================
--- grazer/Makefile.am 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/Makefile.am 2006-08-31 23:15:32 UTC (rev 594)
@@ -8,10 +8,10 @@
noinst_LIBRARIES = libgrazer.a
libgrazer_a_SOURCES = \
- grazer.cpp grazer_show.cpp
+ grazer.cpp grazer_config.cpp grazer_show.cpp
noinst_HEADERS = \
- grazer.hpp
+ grazer.hpp grazer_config.hpp
EXTRA_DIST =
Modified: grazer/grazer.cpp
===================================================================
--- grazer/grazer.cpp 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/grazer.cpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -48,7 +48,7 @@
schema_init ();
// Top config element.
- _config = new sXML ("config", NULL);
+ _config = new GrazerConfigElement ("config", _xs_config);
}
void
@@ -65,351 +65,23 @@
int
Grazer::config_add (sXML *doc)
{
- sXML *config;
- sXML *schema = NULL;
- sXML_Element *ele;
+ sXML *sch;
+ int action;
- config = _config->getFirstElementByTagName ("config");
- if (!config)
+ sch = _xs_config->find_top ("config");
+ if (! sch)
return 0;
- schema = _xs_config->find_node (XS_ELEMENT, "config");
- if (! schema)
- return 0;
+ // Make temporary tree.
+ GrazerConfigElement gce_added ("config", _xs_config);
+ gce_added.init (doc, sch);
- std::list<sXML *>::iterator it;
- for (it = doc->list.begin (); it != doc->list.end (); it++)
- {
- ele = *it;
- config_add_node (config, ele, schema);
- }
+ // Insert it into existing tree.
+ action = _config->insert (&gce_added);
return 0;
}
-sXML_Element *
-Grazer::complex_type_lookup (sXML *doc, XML_Char *name)
-{
- sXML_Element *ele;
- sXML_Attribute *attr;
-
- std::list<sXML *>::iterator it;
- for (it = doc->list.begin (); it != doc->list.end (); it++)
- {
- ele = *it;
- if (std::strcmp (ele->name (), "xs:complexType") == 0)
- if ((attr = ele->getAttribute ("name")))
- if (std::strncmp (name, "zebra:", 6) == 0)
- if (std::strcmp (attr->value (), &name[6]) == 0)
- return ele;
- }
-
- return NULL;
-}
-
-sXML_Element *
-Grazer::find_schema_element (sXML_Element *e0, XML_Char *name)
-{
- sXML_Element *e2, *e3, *e4;
- sXML_Element *type;
- XML_Char *type_str;
- XML_Char *str;
-
- type_str = e0->getAttributeValue ("type");
- if (type_str)
- type = complex_type_lookup (_xs_config->doc (), type_str);
- else
- type = e0->getElement ("xs:complexType");
-
- if (type)
- {
- std::list<sXML *>::iterator it;
- for (it = type->list.begin (); it != type->list.end (); it++)
- {
- e2 = *it;
- if (std::strcmp (e2->name (), "xs:sequence") == 0)
- {
- std::list<sXML *>::iterator it2;
- for (it2 = e2->list.begin (); it2 != e2->list.end (); it2++)
- {
- e3 = *it2;
- if (std::strcmp (e3->name (), "xs:choice") == 0)
- {
- std::list<sXML *>::iterator it3;
-
- for (it3 = e3->list.begin(); it3 != e3->list.end (); it3++)
- {
- e4 = *it3;
- if ((str = e4->getAttributeValue ("name")))
- if (std::strcmp (str, name) == 0)
- return e4;
- }
- }
- else if (std::strcmp (e3->name (), "xs:element") == 0)
- {
- if ((str = e3->getAttributeValue ("name")))
- if (std::strcmp (str, name) == 0)
- return e3;
- }
- }
- }
- else if (std::strcmp (e2->name (), "xs:all") == 0)
- {
- }
- else if (std::strcmp (e2->name (), "xs:choice") == 0)
- {
- std::list<sXML *>::iterator it2;
-
- for (it2 = e2->list.begin (); it2 != e2->list.end (); it2++)
- {
- e3 = *it2;
- if (std::strcmp (e3->name (), "xs:element") == 0)
- if ((str = e3->getAttributeValue ("name")))
- if (std::strcmp (str, name) == 0)
- return e3;
- }
- }
- }
- }
-
- return NULL;
-}
-
-XML_Char *
-Grazer::find_value_by_xpath (sXML_Element *e0, XML_Char *xpath)
-{
- sXML_Element *next = e0;
- sXML_Element *e1;
- sXML_Attribute *a1;
- XML_Char *cp = xpath;
- XML_Char *p;
-
- while (cp != '\0')
- {
- p = strchr (cp, '/');
- if (p == NULL)
- break;
-
- std::string path (cp, (p - cp));
- next = next->getElement ((char *)path.c_str ());
- if (next == NULL)
- return NULL;
-
- cp = p + 1;
- }
-
- // Attribute.
- if (*cp == '@')
- {
- std::list<sXML_Attribute *>::iterator it;
- for (it = next->attrlist.begin (); it != next->attrlist.end (); it++)
- {
- a1 = *it;
- if (std::strcmp (a1->name (), cp + 1) == 0)
- return a1->value ();
- }
- }
- else
- {
- std::list<sXML *>::iterator it;
- for (it = next->list.begin (); it != next->list.end (); it++)
- {
- e1 = *it;
- if (std::strcmp (e1->name (), cp) == 0)
- return e1->value ();
- }
- }
-
- return NULL;
-}
-
-int
-Grazer::is_multiple (sXML_Element *schema)
-{
- XML_Char *maxOccurs;
-
- maxOccurs = schema->getAttributeValue ("maxOccurs");
- if (maxOccurs == NULL)
- return 0;
-
- if (std::strcmp (maxOccurs, "unbounded") != 0
- && atoi (maxOccurs) == 1)
- return 0;
-
- return 1;
-}
-
-sXML_Element *
-Grazer::match_node (sXML_Element *schema_child, sXML_Element *dest,
- sXML_Element *src, sXML_Element *first, sXML_Element *last)
-{
- sXML_Element *ele;
- XML_Char *src_key;
- XML_Char *key_str;
- XML_Char *key;
-
- key_str = schema_child->getAttributeValue ("zebra:key");
- if (key_str)
- {
- src_key = find_value_by_xpath (src, key_str);
- if (src_key == NULL)
- return NULL;
-
-#if 0
- for (ele = first; ele != last->next; ele = ele->next)
- if ((key = find_value_by_xpath (ele, key_str)))
- if (std::strcmp (key, src_key) == 0)
- return ele;
-#endif
- }
-
- return NULL;
-}
-
-sXML_Element *
-Grazer::schema_element_next (sXML_Element *type, sXML_Element *e0)
-{
- sXML_Element *next;
-
- if (e0 == type)
- return NULL;
-
-#if 0
- if (e0 == NULL)
- next = type->list.front ();
- else
- next = e0->next;
-
- if (next != NULL)
- {
- if (std::strcmp (sXML_Name (next), "xs:element") == 0)
- return next;
- else if (std::strcmp (sXML_Name (next), "xs:sequence") == 0)
- return schema_element_next (type, next->list.head);
- else if (std::strcmp (sXML_Name (next), "xs:choice") == 0)
- return schema_element_next (type, next->list.head);
- else if (std::strcmp (sXML_Name (next), "xs:all") == 0)
- return schema_element_next (type, next->list.head);
- }
-#endif
-
- return schema_element_next (type, e0->parent ());
-}
-
-int
-Grazer::config_add_node (sXML_Element *dest, sXML_Element *src,
- sXML_Element *schema)
-{
- sXML_Element *ele;
- sXML_Element *dest_child;
- sXML_Element *sch = NULL, *sch_src = NULL;
- sXML_Element *conf, *conf_first = NULL, *conf_last = NULL;
- sXML_Attribute *attr;
- XML_Char *src_name = src->name ();
- XML_Char *src_val = src->value ();
- XML_Char *sch_name;
-
- sch_src = find_schema_element (schema, src_name);
- if (sch_src == NULL) // Not valid against schema def.
- return 0;
-
- sXML_Element *type;
- XML_Char *type_str;
- type_str = schema->getAttributeValue ("type");
- if (type_str)
- type = complex_type_lookup (_xs_config->doc (), type_str);
- else
- type = schema->getElement ("xs:complexType");
- if (type == NULL) // There is no child under this schema.
- return 0;
-
- std::list<sXML *>::iterator it;
- for (it = dest->list.begin (); it != dest->list.end (); it++)
- {
- conf = *it;
-
- // Find first and last element with the same name.
- if (std::strcmp (conf->name (), src_name) == 0)
- {
-#if 0
- for (conf_first = conf; conf; conf = conf->next)
- {
- if (std::strcmp (sXML_Name (conf), src_name) != 0)
- break;
-
- conf_last = conf;
- }
- goto found;
-#endif
- }
-
- bool found = false;
- // Find previous and next schema for target.
- while ((sch = schema_element_next (type, sch)))
- {
- sch_name = sch->getAttributeValue ("name");
- if (std::strcmp (sch_name, src_name) == 0)
- found = true;
-
- if (std::strcmp (sch_name, conf->name ()) == 0)
- {
- if (found)
- goto found;
- else
- break;
- }
- }
-
- conf_last = conf;
- }
-
- found:
-
- bool is_matched = false;
- if (conf_last)
- {
- if (conf_first)
- {
- if (!is_multiple (sch_src))
- {
- dest_child = conf_first;
- is_matched = true;
- }
- else
- {
- dest_child = match_node (sch_src, dest, src,
- conf_first, conf_last);
- if (dest_child != NULL)
- is_matched = true;
- else
- dest_child = conf_last->insert_element (src_name, src_val);
- }
- }
- else
- dest_child = conf_last->insert_element (src_name, src_val);
- }
- else
- dest_child = dest->add_element (src_name, src_val);
-
- if (!is_matched)
- {
- std::list<sXML_Attribute *>::iterator it;
- for (it = src->attrlist.begin (); it != src->attrlist.end (); it++)
- {
- attr = *it;
- dest_child->add_attribute (attr->name (), attr->value ());
- }
- }
-
- for (it = src->list.begin (); it != src->list.end (); it++)
- {
- ele = *it;
- config_add_node (dest_child, ele, sch_src);
- }
-
- return 0;
-}
-
static inline int
connection_write (union http_out_arg arg, const void *buf, size_t count)
{
Modified: grazer/grazer.hpp
===================================================================
--- grazer/grazer.hpp 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/grazer.hpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -3,6 +3,8 @@
#ifndef _GRAZER_HPP
#define _GRAZER_HPP
+#include "grazer_config.hpp"
+
class Schema;
// Grazer
@@ -23,7 +25,7 @@
void schema_init ();
//
- sXML *config () { return _config; }
+ GrazerConfigElement *config () { return _config; }
private:
// Reference to event manager.
@@ -33,7 +35,7 @@
Logging& _log;
// Config XML tree.
- sXML *_config;
+ GrazerConfigElement *_config;
// Schema definition.
Schema *_xs_exec;
Added: grazer/grazer_config.cpp
===================================================================
--- grazer/grazer_config.cpp 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/grazer_config.cpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -0,0 +1,570 @@
+// %COPYRIGHT%
+
+#include <common.hpp>
+#include <module.hpp>
+#include "lib/sxml.hpp"
+#include "grazer_config.hpp"
+
+GrazerSequence::GrazerSequence (sXML *sch)
+{
+ for (sXML_List::iterator it = sch->list.begin ();
+ it != sch->list.end (); it++)
+ {
+ sXML *sch_child = *it;
+
+ if ((strcmp (sch_child->name (), "xs:sequence")) == 0)
+ _vec.push_back (new GrazerSequence (sch_child));
+ else if ((strcmp (sch_child->name (), "xs:choice")) == 0)
+ _vec.push_back (new GrazerChoice (sch_child));
+ else if ((strcmp (sch_child->name (), "xs:element")) == 0)
+ {
+ XML_Char *sortby = sch_child->getAttributeValue ("zebra:sortby");
+ if (sortby)
+ {
+ if ((strcmp (sortby, "PrefixIPv4")) == 0)
+ _vec.push_back (new GrazerContainerTable<IPv4> (sch_child));
+ else if ((strcmp (sortby, "Integer")) == 0)
+ _vec.push_back (new GrazerContainerSet<int> (sch_child));
+ }
+ else
+ _vec.push_back (new GrazerContainerList (sch_child));
+ }
+ }
+}
+
+GrazerChoice::GrazerChoice (sXML *sch)
+{
+ for (sXML_List::iterator it = sch->list.begin ();
+ it != sch->list.end (); it++)
+ {
+ sXML *sch_child = *it;
+
+ if ((strcmp (sch_child->name (), "xs:sequence")) == 0)
+ _vec.push_back (new GrazerSequence (sch_child));
+ else if ((strcmp (sch_child->name (), "xs:choice")) == 0)
+ _vec.push_back (new GrazerChoice (sch_child));
+ else if ((strcmp (sch_child->name (), "xs:element")) == 0)
+ {
+ XML_Char *sortby = sch_child->getAttributeValue ("zebra:sortby");
+ if (sortby && (strcmp (sortby, "PrefixIPv4") == 0))
+ _vec.push_back (new GrazerContainerTable<IPv4> (sch_child));
+ else
+ _vec.push_back (new GrazerContainerList (sch_child));
+ }
+ }
+}
+
+GrazerAll::GrazerAll (sXML *sch)
+{
+ for (sXML_List::iterator it = sch->list.begin ();
+ it != sch->list.end (); it++)
+ {
+ sXML *sch_child = *it;
+
+ if ((strcmp (sch_child->name (), "xs:element")) == 0)
+ {
+ XML_Char *sortby = sch_child->getAttributeValue ("zebra:sortby");
+ if (sortby && (strcmp (sortby, "PrefixIPv4") == 0))
+ _vec.push_back (new GrazerContainerTable<IPv4> (sch_child));
+ else
+ _vec.push_back (new GrazerContainerList (sch_child));
+ }
+ }
+}
+
+XML_Char *
+GrazerContainerList::get_value_by_xpath (XML_Char *xpath)
+{
+ return NULL;
+}
+
+XML_Char *
+GrazerOrder::get_value_by_xpath (XML_Char *xpath)
+{
+ XML_Char *delim;
+
+ delim = strchr (xpath, '/');
+ if (delim != NULL)
+ *delim = '\0';
+
+ for (std::vector<GrazerContainer *>::iterator it = _vec.begin ();
+ it != _vec.end (); it++)
+ {
+ GrazerContainer *gc = *it;
+ if ((strcmp (gc->name (), delim + 1)) == 0)
+ return gc->get_value_by_xpath (NULL);
+ }
+
+ return NULL;
+}
+
+template<class T>
+int
+GrazerContainerTable<T>::insert (GrazerContainer *gc)
+{
+ GrazerContainerTable<T> *gct_added = (GrazerContainerTable<T> *)gc;
+ TableNode<Prefix<T> > *node;
+ TableNode<Prefix<T> > *node_added;
+ GrazerConfigElement *gce, *gce_added;
+
+ for (node_added = gct_added->_table.begin ();
+ node_added; node_added = gct_added->_table.next (node_added))
+ if ((gce_added = (GrazerConfigElement *)node_added->info))
+ {
+ node = _table.node_get (node_added->p);
+ if ((gce = (GrazerConfigElement *)node->info))
+ {
+ gce->insert (gce_added);
+ gct_added->_table.unlock (node_added);
+ }
+ else
+ {
+ node_added->info = gce;
+ node->info = gce_added;
+ }
+ }
+ return 0;
+}
+
+int
+GrazerOrder::insert (GrazerContainer *added)
+{
+ GrazerOrder *go = (GrazerOrder *)added;
+ std::vector<GrazerContainer *>::iterator it;
+ unsigned int i;
+
+ for (i = 0; i < _vec.size (); i++)
+ {
+ // Insert GrazerContainer.
+ _vec[i]->insert (go->_vec[i]);
+ }
+
+ return 0;
+}
+
+int
+GrazerContainerVector::insert (GrazerContainer *gc)
+{
+ GrazerContainerVector *gcv_added = (GrazerContainerVector *)gc;
+ std::vector<GrazerConfigElement *>::iterator it;
+
+std::cout << "*** GrazerContainerVector::insert\n";
+
+ for (it = gcv_added->_vec.begin (); it != gcv_added->_vec.end (); it++)
+ {
+ GrazerConfigElement *gce_added = *it;
+ GrazerConfigElement *gce = get_element ((*it)->name ());
+ if (gce)
+ gce->insert (gce_added);
+ }
+
+ return 0;
+}
+
+XML_Char *
+GrazerConfigElement::get_value_by_xpath_func (XML_Char *xpath)
+{
+ XML_Char *p = xpath;
+ XML_Char *delim;
+ GrazerConfigAttribute *attr;
+
+ if (*p == '@')
+ {
+ attr = lookup_attribute (p + 1);
+ if (attr)
+ return attr->value ();
+
+ return NULL;
+ }
+
+ delim = strchr (p, '/');
+ if (delim != NULL)
+ *delim = '\0';
+
+ if (delim && _order)
+ return _order->get_value_by_xpath (delim + 1);
+
+ return value ();
+}
+
+XML_Char *
+GrazerConfigElement::get_value_by_xpath (XML_Char *xpath)
+{
+ XML_Char *copy;
+ XML_Char *val;
+
+ copy = strdup (xpath);
+
+ val = get_value_by_xpath_func (copy);
+
+ free (copy);
+
+ return val;
+}
+
+int
+GrazerConfigElement::init_order (sXML *sch)
+{
+ sXML *type;
+ sXML *sch_child;
+ XML_Char *type_str;
+
+ type_str = sch->getAttributeValue ("type");
+ if (type_str)
+ type = _xs->complex_type_lookup (type_str);
+ else
+ type = sch->getElement ("xs:complexType");
+
+ if (type)
+ {
+ // There must be only one sequence, choice or all under complexType.
+ if ((sch_child = type->getElement ("xs:sequence")))
+ _order = new GrazerSequence (sch_child);
+ else if ((sch_child = type->getElement ("xs:choice")))
+ _order = new GrazerChoice (sch_child);
+ else if ((sch_child = type->getElement ("xs:all")))
+ _order = new GrazerAll (sch_child);
+
+ // Initialize Attributes.
+ for (sXML_List::iterator it = type->list.begin ();
+ it != type->list.end (); it++)
+ {
+ sch_child = *it;
+
+ if ((strcmp (sch_child->name (), "xs:attribute")) == 0)
+ {
+ XML_Char *attrname = sch_child->getAttributeValue ("name");
+ if (attrname)
+ _attrs.push_back (new GrazerConfigAttribute (attrname));
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+GrazerConfigElement::insert (GrazerConfigElement *added)
+{
+ if (_order)
+ {
+ if (added->_order)
+ return _order->insert (added->_order);
+ }
+ else
+ {
+ _order = added->_order;
+ added->_order = NULL;
+ }
+
+ return 0;
+}
+
+GrazerContainer *
+GrazerOrder::get_container (XML_Char *name)
+{
+ std::vector<GrazerContainer *>::iterator it;
+
+ for (it = _vec.begin (); it != _vec.end (); it++)
+ {
+ GrazerContainer *gc = (*it)->get_container (name);
+ if (gc)
+ return gc;
+ }
+
+ return NULL;
+}
+
+GrazerContainer *
+GrazerContainerList::get_container (XML_Char *name)
+{
+ if ((strcmp (this->name (), name)) == 0)
+ return this;
+
+ return NULL;
+}
+
+void
+GrazerContainerList::init (sXML *conf, sXML *sch, Schema *xs)
+{
+ GrazerConfigElement *gce;
+ XML_Char *name = sch->getAttributeValue ("name");
+
+ if (name)
+ {
+ gce = new GrazerConfigElement (name, xs);
+ gce->init (conf, sch);
+ _list.push_back (gce);
+ }
+}
+
+int
+GrazerContainerList::insert (GrazerContainer *gc)
+{
+ GrazerContainerList *gcl_added = (GrazerContainerList *)gc;
+ std::list<GrazerConfigElement *>::iterator it;
+
+std::cout << "*** GrazerContainerList::insert\n";
+
+ for (it = gcl_added->_list.begin (); it != gcl_added->_list.end (); it++)
+ {
+ GrazerConfigElement *gce_added = *it;
+ GrazerConfigElement *gce = get_element ((*it)->name ());
+ if (gce)
+ gce->insert (gce_added);
+ else
+ _list.push_back (gce_added);
+ }
+
+ return 0;
+}
+
+GrazerConfigElement *
+GrazerContainerList::get_element (XML_Char *name)
+{
+ for (std::list<GrazerConfigElement *>::iterator it = _list.begin ();
+ it != _list.end (); it++)
+ {
+ GrazerConfigElement *gce = *it;
+
+ if ((strcmp (gce->name (), name)) == 0)
+ return gce;
+ }
+ return NULL;
+}
+
+template <typename T>
+void
+GrazerContainerSet<T>::init (sXML *conf, sXML *sch, Schema *xs)
+{
+ GrazerConfigElement *gce;
+ XML_Char *name = sch->getAttributeValue ("name");
+
+ if (name)
+ {
+ gce = new GrazerConfigElement (name, xs);
+ gce->init (conf, sch);
+ _set.insert (gce);
+ }
+}
+
+template <class T>
+GrazerContainer *
+GrazerContainerTable<T>::get_container (XML_Char *name)
+{
+ if ((strcmp (this->name (), name)) == 0)
+ return this;
+
+ return NULL;
+}
+
+template <class T>
+XML_Char *
+GrazerContainerTable<T>::get_value_by_xpath (XML_Char *xpath)
+{
+ if (*xpath == '@')
+ {
+ Prefix<T> p ((const XML_Char *)xpath + 1);
+ TableNode<Prefix<T> > *node = _table.lookup (p);
+ if (node)
+ {
+ _table.unlock (node);
+ GrazerConfigElement *gce = (GrazerConfigElement *)node->info;
+ return gce->value ();
+ }
+ }
+
+ return NULL;
+}
+
+template <class T>
+void
+GrazerContainerTable<T>::init (sXML *conf, sXML *sch, Schema *xs)
+{
+ GrazerConfigElement *gce;
+ XML_Char *name = sch->getAttributeValue ("name");
+
+ if (name)
+ {
+ gce = new GrazerConfigElement (name, xs);
+ gce->init (conf, sch);
+
+ XML_Char *key_value = sch->getAttributeValue ("zebra:key");
+ if (key_value)
+ {
+ const XML_Char *value = conf->getValueByXpath (key_value);
+
+ Prefix<T> p (value);
+ TableNode<Prefix<T> > *node = _table.node_get (p);
+ node->info = gce;
+ }
+ }
+}
+
+template <class T>
+void
+GrazerContainerTable<T>::build (std::string &str, int depth)
+{
+ TableNode<Prefix<T> > *node;
+ GrazerConfigElement *gce;
+
+ for (node = _table.begin (); node; node = _table.next (node))
+ if ((gce = (GrazerConfigElement *)node->info))
+ gce->build (str, depth + 1);
+}
+
+template <class T>
+GrazerConfigElement *
+GrazerContainerTable<T>::get_element (XML_Char *name)
+{
+ TableNode< Prefix<T> > *node;
+ GrazerConfigElement *gce;
+
+ for (node = _table.begin (); node; node = _table.next (node))
+ if ((gce = (GrazerConfigElement *)node->info))
+ if ((strcmp (gce->name (), name)) == 0)
+ return gce;
+
+ return NULL;
+}
+
+GrazerConfigAttribute *
+GrazerConfigElement::lookup_attribute (XML_Char *name)
+{
+ std::vector<GrazerConfigAttribute *>::iterator it;
+ GrazerConfigAttribute *gca;
+
+ for (it = _attrs.begin (); it != _attrs.end (); it++)
+ {
+ gca = *it;
+ if ((strcmp (gca->name (), name) == 0))
+ return gca;
+ }
+ return NULL;
+}
+
+int
+GrazerConfigElement::init (sXML *conf, sXML *sch)
+{
+ // If there is no child under this config, initialize it.
+ // if (!_order)
+ init_order (sch);
+
+ // Set element value.
+ if (conf->value ())
+ set_value (conf->value ());
+
+std::cerr << "*** gce->init() 0 "<< conf->name() <<"\n";
+
+ // Set schema element to grazer element.
+ set_schema (sch);
+
+ // Set attribute values.
+ for (sXML_Attribute_List::iterator it = conf->attrlist.begin ();
+ it != conf->attrlist.end (); it++)
+ {
+ sXML_Attribute *attr = *it;
+
+ GrazerConfigAttribute *gca = lookup_attribute (attr->name ());
+ if (gca && attr->value ())
+ gca->set_value (attr->value ());
+ }
+
+std::cerr << "*** gce->init() 1\n";
+
+ // Iterate all children nodes.
+ for (std::list<sXML *>::iterator it = conf->list.begin ();
+ it != conf->list.end (); it++)
+ {
+ sXML_Element *conf_child = *it;
+ sXML_Element *sch_child;
+
+std::cerr << "*** gce->init() 2\n";
+
+ // Lookup schema definition for this child.
+ sch_child = _xs->find_element (sch, conf_child->name ());
+ if (sch_child)
+ {
+ GrazerContainer *gc = _order->get_container (conf_child->name ());
+ if (gc)
+ {
+ // Init child to set values under this container.
+ gc->init (conf_child, sch_child, _xs);
+ _valid = true;
+ }
+ }
+ // Something wrong.
+ else
+ std::cerr << "no schema def\n";
+ }
+
+std::cerr << "*** gce->init() 3\n";
+
+ return 0;
+}
+
+void
+GrazerOrder::build (std::string &str, int depth)
+{
+ for (std::vector<GrazerContainer *>::iterator it = _vec.begin ();
+ it != _vec.end (); it++)
+ {
+ GrazerContainer *gc = *it;
+ gc->build (str, depth);
+ }
+}
+
+void
+GrazerContainerList::build (std::string &str, int depth)
+{
+ for (std::list<GrazerConfigElement *>::iterator it = _list.begin ();
+ it != _list.end (); it++)
+ {
+ GrazerConfigElement *gce = *it;
+ gce->build (str, depth + 1);
+ }
+}
+
+void
+GrazerConfigAttribute::build (std::string &str, int depth)
+{
+ if (value ())
+ {
+ str += " ";
+ str += name ();
+ str += "=";
+ str += '"';
+ str += value ();
+ str += '"';
+ }
+}
+
+void
+GrazerConfigElement::build (std::string &str, int depth)
+{
+ std::string indent (depth * 2, ' ');
+
+ str += indent;
+ str += "<";
+ str += name ();
+
+ for (std::vector<GrazerConfigAttribute *>::iterator it = _attrs.begin ();
+ it != _attrs.end (); it++)
+ {
+ GrazerConfigAttribute *gca = *it;
+ gca->build (str, depth);
+ }
+
+ str += ">";
+ if (value ())
+ str += value ();
+ str += "\n";
+
+ if (_order)
+ _order->build (str, depth);
+
+ str += indent;
+ str += "</";
+ str += name ();
+ str += ">\n";
+}
Added: grazer/grazer_config.hpp
===================================================================
--- grazer/grazer_config.hpp 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/grazer_config.hpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -0,0 +1,222 @@
+// %COPYRIGHT%
+
+#ifndef _GRAZER_CONFIG_HPP
+#define _GRAZER_CONFIG_HPP
+
+#include <list>
+#include <vector>
+
+#include "lib/prefix.hpp"
+#include "lib/table.hpp"
+#include "lib/cli.hpp"
+#include "lib/schema.hpp"
+
+class GrazerOrder;
+
+// Config base class.
+class GrazerConfig
+{
+ friend class Grazer;
+
+public:
+ GrazerConfig () { }
+ GrazerConfig (XML_Char *name)
+ : _name (NULL),
+ _value (NULL),
+ _sch (NULL),
+ _valid (false) { _name = strdup (name); }
+ virtual ~GrazerConfig () { }
+
+ XML_Char *name () { return _name; }
+ XML_Char *value () { return _value; }
+ void set_value (XML_Char *value)
+ {
+ if (value)
+ _value = strdup (value);
+ }
+ bool is_valid () { return _valid; }
+ void set_schema (sXML *sch) { _sch = sch; }
+
+private:
+ XML_Char *_name;
+ XML_Char *_value;
+ sXML *_sch;
+
+protected:
+ bool _valid;
+
+ virtual void build (std::string &str, int depth) = 0;
+};
+
+class GrazerConfigAttribute: public GrazerConfig
+{
+ friend class GrazerConfigElement;
+
+public:
+ GrazerConfigAttribute (XML_Char *name)
+ : GrazerConfig (name) { }
+
+ void build (std::string &str, int depth);
+};
+
+class GrazerConfigElement: public GrazerConfig
+{
+public:
+ GrazerConfigElement () { }
+ GrazerConfigElement (XML_Char *name, Schema *xs)
+ : GrazerConfig (name),
+ _xs (xs),
+ _order (NULL) { }
+
+ void build (std::string &str, int depth);
+ int init (sXML *c0, sXML *sch);
+ int insert (GrazerConfigElement *added);
+ GrazerConfigAttribute *lookup_attribute (XML_Char *name);
+
+private:
+ Schema *_xs;
+ std::vector<GrazerConfigAttribute *> _attrs;
+ GrazerOrder *_order;
+
+ int init_order (sXML *sch);
+ GrazerConfigElement *lookup_child (XML_Char *name);
+ XML_Char *get_value_by_xpath (XML_Char *xpath);
+ XML_Char *get_value_by_xpath_func (XML_Char *xpath);
+};
+
+// Container base class.
+class GrazerContainer
+{
+public:
+ GrazerContainer () : _name (NULL) { }
+ GrazerContainer (XML_Char *name) : _name (NULL) { _name = strdup (name); }
+ virtual ~GrazerContainer () { free (_name); }
+
+ virtual void build (std::string &str, int depth) = 0;
+ virtual void init (sXML *conf, sXML *sch, Schema *xs) = 0;
+ virtual GrazerContainer *get_container (XML_Char *name) = 0;
+ virtual GrazerConfigElement *get_element (XML_Char *name) = 0;
+ XML_Char *name () { return _name; }
+ virtual XML_Char *get_value_by_xpath (XML_Char *xpath) = 0;
+ virtual int insert (GrazerContainer *gc) = 0;
+
+private:
+ XML_Char *_name;
+};
+
+class GrazerOrder: public GrazerContainer
+{
+ friend class GrazerConfigElement;
+
+public:
+ virtual ~GrazerOrder () { }
+
+private:
+ GrazerContainer *get_container (XML_Char *name);
+ void build (std::string &str, int depth);
+ void init (sXML *conf, sXML *sch, Schema *xs) { }
+ int insert (GrazerContainer *added);
+ GrazerConfigElement *get_element (XML_Char *name) { return NULL; }
+ XML_Char *get_value_by_xpath (XML_Char *xpath);
+
+protected:
+ std::vector<GrazerContainer *> _vec;
+};
+
+class GrazerSequence: public GrazerOrder
+{
+public:
+ GrazerSequence (sXML *sch);
+
+private:
+};
+
+class GrazerChoice: public GrazerOrder
+{
+public:
+ GrazerChoice (sXML *sch);
+
+private:
+};
+
+class GrazerAll: public GrazerOrder
+{
+public:
+ GrazerAll (sXML *sch);
+
+private:
+};
+
+class GrazerContainerVector: public GrazerContainer
+{
+public:
+ GrazerContainerVector (sXML *sch) :
+ GrazerContainer (sch->getAttributeValue ("name")) { }
+
+private:
+ std::vector<GrazerConfigElement *> _vec;
+
+ void build (std::string &str, int depth) { }
+ void init (sXML *conf, sXML *sch) { }
+ GrazerConfigElement *get_element (XML_Char *name) { return NULL; }
+ int insert (GrazerContainer *gc);
+};
+
+class GrazerContainerList: public GrazerContainer
+{
+public:
+ GrazerContainerList (sXML *sch) :
+ GrazerContainer (sch->getAttributeValue ("name")) { }
+
+private:
+ std::list<GrazerConfigElement *> _list;
+
+ void build (std::string &str, int depth);
+ void init (sXML *conf, sXML *sch, Schema *xs);
+ // void insert (sXML *conf, sXML *sch, Schema *xs);
+ GrazerContainer *get_container (XML_Char *name);
+ GrazerConfigElement *get_element (XML_Char *name);
+ XML_Char *get_value_by_xpath (XML_Char *xpath);
+ int insert (GrazerContainer *gc);
+};
+
+template <typename T>
+class GrazerContainerSet: public GrazerContainer
+{
+public:
+ GrazerContainerSet<T> (sXML *sch) :
+ GrazerContainer (sch->getAttributeValue ("name")) { }
+
+private:
+ // std::set<GrazerConfigElement *, GrazerConfigSetComp> _set;
+ std::set<GrazerConfigElement *> _set;
+
+ void build (std::string &str, int depth) { }
+ void init (sXML *conf, sXML *sch, Schema *xs);
+ // void insert (sXML *conf, sXML *sch, Schema *xs);
+ GrazerContainer *get_container (XML_Char *name) { return NULL; }
+ GrazerConfigElement *get_element (XML_Char *name) { return NULL; }
+ XML_Char *get_value_by_xpath (XML_Char *xpath) { return NULL; }
+ int insert (GrazerContainer *gc) { return 0; }
+};
+
+template <class T>
+class GrazerContainerTable: public GrazerContainer
+{
+public:
+ GrazerContainerTable<T> (sXML *sch) :
+ GrazerContainer (sch->getAttributeValue ("name")) { }
+
+private:
+ Table<Prefix<T> > _table;
+
+ void build (std::string &str, int depth);
+ void init (sXML *conf, sXML *sch, Schema *xs);
+ // void insert (sXML *conf, sXML *sch, Schema *xs);
+ GrazerContainer *get_container (XML_Char *name);
+ GrazerConfigElement *get_element (XML_Char *name);
+ XML_Char *get_value_by_xpath (XML_Char *xpath);
+ int insert (GrazerContainer *gc);
+};
+
+#endif /* _GRAZER_CONFIG_HPP */
Modified: grazer/grazer_show.cpp
===================================================================
--- grazer/grazer_show.cpp 2006-04-17 17:14:23 UTC (rev 593)
+++ grazer/grazer_show.cpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -6,6 +6,7 @@
#include <connector.hpp>
#include <module.hpp>
#include "grazer.hpp"
+#include "grazer_config.hpp"
CLI (show_running_config)
{
@@ -13,7 +14,7 @@
if (grazer)
{
- grazer->config ()->string (str);
+ grazer->config ()->build (str, 0);
cli_out (cli, "%s", str.c_str ());
}
Modified: lib/http.hpp
===================================================================
--- lib/http.hpp 2006-04-17 17:14:23 UTC (rev 593)
+++ lib/http.hpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -15,6 +15,9 @@
// For shell output.
int fd;
+ // For shell show running-config.
+
+
// For grazer output.
Connection *c;
Modified: lib/schema.cpp
===================================================================
--- lib/schema.cpp 2006-04-17 17:14:23 UTC (rev 593)
+++ lib/schema.cpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -256,6 +256,27 @@
return NULL;
}
+#if 0
+sXML_Element *
+Schema::type_lookup (XML_Char *name)
+{
+ sXML *child;
+ XML_Char *type_str;
+
+ child = find_schema_element (_doc, name);
+ if (child)
+ {
+ type_str = child->getAttributeValue ("type");
+ if (type_str)
+ return complex_type_lookup (_doc, type_str);
+ else
+ return child->getElement ("xs:complexType");
+ }
+
+ return NULL;
+}
+#endif
+
void
Schema::token_range_get (sXML_Element *ele, std::string& range,
unsigned long& min_val, unsigned long& max_val)
@@ -1046,31 +1067,80 @@
return h1;
}
+
// Utility.
sXML_Element *
-Schema::find_node (xs_type type, XML_Char *name)
+Schema::lookup_element_sub (sXML *sch, XML_Char *name)
{
- sXML_Element *parent = _doc;
- sXML_Element *ele;
- XML_Char *type_str;
- XML_Char *val;
+ std::cerr << "** schema lookup_element_sub \n";
- if (type == XS_ELEMENT)
- type_str = "xs:element";
- else if (type == XS_ATTRIBUTE)
- type_str = "xs:attribute";
+ for (sXML_List::iterator it = sch->list.begin ();
+ it != sch->list.end (); it++)
+ {
+ sXML_Element *sch_child = *it;
+ sXML_Element *sch_ret;
+ XML_Char *name_val;
+
+ std::cerr << "** schema " << sch_child->name () << "\n";
+
+ if ((strcmp (sch_child->name (), "xs:choice")) == 0)
+ {
+ if ((sch_ret = lookup_element_sub (sch_child, name)))
+ return sch_ret;
+ }
+ else if ((strcmp (sch_child->name (), "xs:sequence")) == 0)
+ {
+ if ((sch_ret = lookup_element_sub (sch_child, name)))
+ return sch_ret;
+ }
+ else if ((strcmp (sch_child->name (), "xs:element")) == 0)
+ {
+ if ((name_val = sch_child->getAttributeValue ("name")))
+ if ((strcmp (name_val, name)) == 0)
+ return sch_child;
+ }
+ }
+
+ return NULL;
+}
+
+sXML_Element *
+Schema::find_element (sXML *sch, XML_Char *name)
+{
+ XML_Char *type_val;
+ sXML_Element *sch_ctype;
+ sXML_Element *sch_child;
+
+ type_val = sch->getAttributeValue ("type");
+ if (type_val)
+ sch_ctype = complex_type_lookup (type_val);
else
- return NULL;
+ sch_ctype = sch->getElement ("xs:complexType");
- sXML_List::iterator it;
- for (it = parent->list.begin (); it != parent->list.end (); it++)
+ if (sch_ctype)
{
- ele = *it;
- if (std::strcmp (ele->name (), type_str) == 0)
- if ((val = ele->getAttributeValue ("name")))
- if (std::strcmp (val, name) == 0)
- return ele;
+ if ((sch_child = sch_ctype->getElement ("xs:sequence")))
+ return lookup_element_sub (sch_child, name);
+ else if ((sch_child = sch_ctype->getElement ("xs:choice")))
+ return lookup_element_sub (sch_child, name);
+ else if ((sch_child = sch_ctype->getElement ("xs:all")))
+ return lookup_element_sub (sch_child, name);
}
return NULL;
}
+
+sXML_Element *
+Schema::find_top (XML_Char *name)
+{
+ sXML_Element *top;
+ XML_Char *name_str;
+
+ top = _doc->getElement ("xs:element");
+ if (top)
+ if ((name_str = top->getAttributeValue ("name")))
+ if (strcmp (name_str, name) == 0)
+ return top;
+
+ return NULL;
+}
Modified: lib/schema.hpp
===================================================================
--- lib/schema.hpp 2006-04-17 17:14:23 UTC (rev 593)
+++ lib/schema.hpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -54,7 +54,9 @@
//
sXML *doc () { return _doc; }
- sXML_Element *find_node (xs_type type, XML_Char *name);
+ sXML_Element *find_element (sXML *sch, XML_Char *name);
+ sXML_Element *find_top (XML_Char *name);
+ sXML_Element *complex_type_lookup (XML_Char *name);
private:
// CLI search path.
@@ -78,7 +80,6 @@
void cel_no_set (CliVector *, void *);
sXML_Element *simple_type_lookup (sXML *parent, XML_Char *name);
- sXML_Element *complex_type_lookup (XML_Char *name);
void token_range_get (sXML_Element *ele, std::string& range,
unsigned long& min_val, unsigned long &max_val);
XML_Char *help_get (XML_Char *cli_str);
@@ -117,6 +118,8 @@
uint32_t str2module_bits (XML_Char *str);
uint32_t module_bits_get (XML_Char *str);
+
+ sXML_Element *lookup_element_sub (sXML *sch, XML_Char *name);
};
#endif /* _SCHEMA_HPP */
Modified: ncore/xml/ip-route.xsd
===================================================================
--- ncore/xml/ip-route.xsd 2006-04-17 17:14:23 UTC (rev 593)
+++ ncore/xml/ip-route.xsd 2006-08-31 23:15:32 UTC (rev 594)
@@ -114,7 +114,8 @@
<xs:element name="route" minOccurs="0" maxOccurs="unbounded"
zebra:cli="route"
zebra:help="Establish static routes"
- zebra:key="@prefix">
+ zebra:key="@prefix"
+ zebra:sortby="PrefixIPv4">
<xs:complexType>
<xs:sequence>
@@ -134,7 +135,6 @@
zebra:help="Interface Name"
zebra:callback="ip_route"
zebra:nocallback="no_ip_route"/>
-
</xs:choice>
<xs:element name="distance"
@@ -146,6 +146,13 @@
zebra:nocallback="no_ip_route_distance"/>
</xs:sequence>
+<!-- <xs:attribute name="distance"
+ type="zebra:distance"
+ zebra:cli="RANGE"
+ zebra:help="Distance metric for this route"
+ zebra:callback="ip_route_distance"
+ zebra:nocallback="no_ip_route_distance"/> -->
+
</xs:complexType>
</xs:element>
Modified: shell/command.cpp
===================================================================
--- shell/command.cpp 2006-04-17 17:14:23 UTC (rev 593)
+++ shell/command.cpp 2006-08-31 23:15:32 UTC (rev 594)
@@ -330,8 +330,8 @@
if (_parser_state->mtype == EXEC_MODE)
path = (char *) module_bit2path (bit);
else
- // path = "/tmp/.grazer";
- path = (char *) module_bit2path (bit);
+ path = (char *) module_bit2path (MODULE_BIT::GRAZER);
+ // path = (char *) module_bit2path (bit);
// Message type.
http.request.set_method (HttpMessage::POST);
@@ -366,7 +366,6 @@
http.request.set_header ("User-Agent", "shell");
-
// Body.
http.request.set_body (xml);
@@ -379,6 +378,21 @@
{
http.response.out_func = shell_write;
http.response.out_arg.fd = STDOUT_FILENO;
+#if 0
+ // Save XML format config.
+ if (std::strcmp (http.request.request_uri ().c_str (),
+ "/exec?/exec-mode/show/running-config") == 0)
+ {
+ http.response.out_func = shell_save_running_config;
+ http.response.out_arg.
+ }
+ // Regular commands.
+ else
+ {
+ http.response.out_func = shell_write;
+ http.response.out_arg.fd = STDOUT_FILENO;
+ }
+#endif
http.response.read (http.fd ());
http.shutdown ();
}
Modified: shell/xml/bgp.xsd
===================================================================
--- shell/xml/bgp.xsd 2006-04-17 17:14:23 UTC (rev 593)
+++ shell/xml/bgp.xsd 2006-08-31 23:15:32 UTC (rev 594)
@@ -1026,11 +1026,11 @@
type="zebra:bgp-distance-value"
zebra:cli="RANGE"
zebra:help="Distance for routes internal to the AS"/>
- <xs:attribute name="external"
+<!-- <xs:attribute name="external"
type="zebra:bgp-distance-value"
zebra:cli="RANGE"
zebra:help="Distance for local routes"
- zebra:callback="bgp_distance_bgp"/>
+ zebra:callback="bgp_distance_bgp"/> -->
</xs:complexType>
</xs:element>
<xs:element name="mbgp"
@@ -1045,11 +1045,11 @@
type="zebra:bgp-mbgp-distance-value"
zebra:cli="RANGE"
zebra:help="Distance for routes internal to the AS"/>
- <xs:attribute name="external"
+<!-- <xs:attribute name="external"
type="zebra:bgp-mbgp-distance-value"
zebra:cli="RANGE"
zebra:help="Distance for local routes"
- zebra:callback="bgp_distance_bgp"/>
+ zebra:callback="bgp_distance_bgp"/> -->
</xs:complexType>
</xs:element>
</xs:sequence>
Modified: shell/xml/config.xsd
===================================================================
--- shell/xml/config.xsd 2006-04-17 17:14:23 UTC (rev 593)
+++ shell/xml/config.xsd 2006-08-31 23:15:32 UTC (rev 594)
@@ -55,12 +55,12 @@
zebra:key="@name"
zebra:module="NCORE|LOCAL"/>
- <xs:element name="ip" type="zebra:ip" minOccurs="0"
+ <xs:element name="ip" type="zebra:ip" minOccurs="0" maxOccurs="1"
zebra:cli="ip"
zebra:help="Global IP configuration subcommands"
zebra:module="NCORE"/>
+<!--
-
<xs:element name="firewall"
zebra:cli="firewall"
zebra:help="Configure Firewall"
@@ -72,10 +72,7 @@
zebra:help="Configure NAT"
zebra:callback="nat_config"
zebra:nocallback="no_nat_config"/>
-
-
-
-
+-->
<xs:element name="router" minOccurs="0"
zebra:cli="router"
zebra:help="Enable a routing process">
@@ -89,11 +86,13 @@
zebra:callback="router_rip"
zebra:nocallback="no_router_rip"
zebra:module="RIP"/>
+
<xs:element name="ospf" type="zebra:ospf"
minOccurs="0" maxOccurs="unbounded"
zebra:cli="ospf"
zebra:help="Open Shortest Path First (OSPF)"
zebra:key="@process-id"
+ zebra:sortby="Integer"
zebra:module="OSPFv2"/>
<xs:element name="bgp" type="zebra:bgp"
minOccurs="0" maxOccurs="unbounded"
@@ -101,22 +100,18 @@
zebra:help="Border Gateway Protocol (BGP)"
zebra:key="@as-number"
zebra:module="BGP"/>
+
</xs:sequence>
</xs:complexType>
</xs:element>
- <xs:element name="common" type="zebra:common" minOccurs="0" />
+ <xs:element name="common" type="zebra:common" minOccurs="0"/>
<xs:element name="no" minOccurs="0"
zebra:cli="no"
zebra:help="Negate a command or set its defaults"
zebra:affirmative="yes"/>
- <xs:element name="no" minOccurs="0"
- zebra:cli="no"
- zebra:help="Negate a command or set its defaults"
- zebra:affirmative="yes"/>
-
</xs:sequence>
</xs:complexType>
</xs:element>
Modified: shell/xml/exec.xsd
===================================================================
--- shell/xml/exec.xsd 2006-04-17 17:14:23 UTC (rev 593)
+++ shell/xml/exec.xsd 2006-08-31 23:15:32 UTC (rev 594)
@@ -174,7 +174,17 @@
zebra:privilege="15"
zebra:callback="show_running_config"
zebra:module="GRAZER"/>
-
+<!--
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="xml"
+ zebra:cli="xml"
+ zebra:help="Config in XML format"
+ zebra:callback="show_running_config"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+-->
</xs:choice>
</xs:complexType>
</xs:element>
Modified: shell/xml/rip.xsd
===================================================================
--- shell/xml/rip.xsd 2006-04-17 17:14:23 UTC (rev 593)
+++ shell/xml/rip.xsd 2006-08-31 23:15:32 UTC (rev 594)
@@ -45,7 +45,7 @@
zebra:help="Administrative distance">
<xs:complexType>
<xs:sequence>
- <xs:element name=""/>
+<!-- <xs:element name=""/>-->
</xs:sequence>
<xs:attribute name="value" type="zebra:distance"
zebra:cli="RANGE"
More information about the Source-changes
mailing list