1 #ifndef _MANET_GRAPHML
2 #define _MANET_GRAPHML
3 #define MAXXMLIDLENGTH 255
4 
5 #include <manetGraph.h>
6 #include <protoQueue.h>
7 #include <libxml/encoding.h>
8 #include <libxml/xmlwriter.h>
9 #include <libxml/xmlreader.h>
10 
11 #define MY_GRAPHML_ENCODING "UTF-8"
12 
13 // NOTES
14 // Basic GraphML parsing to instantiate a ProtoGraph NetGraph is supported
15 //
16 // Current Limitations:
17 // 1) The NetGraph::Node could be extended here to have a list of child graphs to allow support of
18 //    nested graphs per the GraphML specifications, but that has not yet been implemented.
19 // 2) Handling of "default" attributes can be made more efficient.  Currently, graph elements are
20 //    given Attribute instances for those in the key that have default values specified.  This could
21 //    be made more efficient by having the "GetAttribute()" and AttributeIterator code search the
22 //    attribute key list for any defaults rather than each element having its own instances of default
23 //    attributes
24 // 3) Node ports are supported but nested ports and nested graphs are not yet supported
25 
26 
27 class ManetGraphMLParser
28 {
29     public:
30         virtual ~ManetGraphMLParser();
31 
32         // TBD - should this public attribute interface stuff be moved to a base ManetGraphML class that the Parser inherits?
33         enum AttributeType {INVALID = 0, BOOL, INT, LONG, FLOAT, DOUBLE, STRING};
34         enum AttributeDomain {NONE = 0, GRAPH, NODE, EDGE, ALL};
35 
36         static AttributeType GetAttributeType(const char* text);
37         static AttributeDomain GetAttributeDomain(const char* text);
38 
39         class Attribute
40         {
41             public:
42                 const char* GetName() const = 0;
43                 const char* GetValue() const = 0;
44         };  // end class ManetGraphMLParser::Attribute
45 
46         // Attribute set / get methods
47         bool SetGraphAttribute(const char* name, const char* value);
48         bool SetNodeAttribute(const NetGraph::Node& node, const char* name, AttributeType type, const char* value);
49         bool SetInterfaceAttribute(const NetGraph::Interface& iface, const char* name, AttributeType type, const char* value);
50         bool SetLinkAttribute(const NetGraph::Link& link, const char* name, AttributeType type, const char* value);
51 
52         const Attribute* GetGraphAttribute(const char* name);
53         const Attribute* GetNodeAttribute(const NetGraph::Node& node, const char* name);
54         const Attribute* GetInterfaceAttribute(const NetGraph::Interface& iface, const char* name);
55         const Attribute* GetLinkAttribute(const NetGraph::Link& link, const char* name);
56 
57         // TBD - GraphAttributeIterator, NodeAttributeIterator, InterfaceAttributeIterator, and LinkAttributeIterator
58 
59         bool Read(const char* path, NetGraph& graph);   // load graph from GraphML file
60 
61         bool Write(NetGraph& graph, const char* path);  // make GraphML file from graph
62 
63 
64     protected:
65         class AttributeKey : public ProtoQueue::Item
66         {
67             public:
68                 AttributeKey();
69                 bool Init(const char* name, const char* id, AttributeType type, AttributeDomain domain);
70                 bool Init(const char* name, const char* id, const char* type, const char* domain);
71                 ~AttributeKey();
72 
73                 bool SetDefaultValue(const char* value);
GetDefaultValue()74                 const char& GetDefaultValue() const
75                     {return attr_default;}
76 
GetName()77                 const char* GetName() const
78                     {return attr_name;}
GetId()79                 const char* GetId() const
80                     {return ((NULL != attr_id) ? attr_id : attr_name);}
GetType()81                 AttributeType GetType() const
82                     {return attr_type;}
GetDomain()83                 AttributeDomain GetDomain() const
84                     {return attr_domain;}
85 
86             private:
87                 char*   attr_name;
88                 char*   attr_id;  // if NULL, then id == name
89                 Type    attr_type
90                 Domain  attr_domain;
91                 char*   attr_default;
92 
93         };  // end class ManetGraphMLParser::AttributeKey
94 
95         class AttributeNameList : public ProtoIndexedQueue<AttributeKey>
96         {
97             private:
GetKey(const ProtoQueue::Item & item)98                 const char* GetKey(const ProtoQueue::Item& item) const
99                     {return static_cast<const AttributeKey&>(item).GetName();}
GetKeysize(const ProtoQueue::Item & item)100                 unsigned int GetKeysize(const ProtoQueue::Item& item) const
101                     {return 8*strlen(static_cast<const AttributeKey&>(item).GetName());}
102         };  // end class ManetGraphMLParser::AttributeNameList
103 
104         class AttributeIdList : public ProtoIndexedQueue<AttributeKey>
105         {
106             private:
GetKey(const ProtoQueue::Item & item)107                 const char* GetKey(const ProtoQueue::Item& item) const
108                     {return static_cast<const AttributeKey&>(item).GetId();}
GetKeysize(const ProtoQueue::Item & item)109                 unsigned int GetKeysize(const ProtoQueue::Item& item) const
110                     {return 8*strlen(static_cast<const AttributeKey&>(item).GetId());}
111 
112         };  // end class ManetGraphMLParser::AttributeNameList
113 
114 
115         class GenericAttribute : public Attribute, public ProtoTree::Item
116         {
117             public:
118                 virtual ~GenericAttribute();
119 
GetName()120                 const char* GetName() const
121                     {return attr_key.GetName();}
122 
GetValue()123                 const char* GetValue() const
124                     {return ((NULL != attr_value) ? attr_value : attr_key.GetDefaultValue());}
125 
126             protected:
127                 friend class ManetGraphMLParser;
128                 GenericAttribute(AttributeKey& key);
129 
GetId()130                 const char* GetId() const
131                     {return attr_key.GetId();}
132 
133                 bool SetValue(const char* value);
134                 virtual ~Attribute();
135 
136                 // ProtoTree::Item required overrides
GetKey()137                 const char* GetKey() const
138                     {return attr_key.GetId();}
GetKeysize()139                 unsigned int GetKeysize() const
140                     {return (strlen(attr_key.GetId() << 3);}
141 
142             private:
143                 AttributeKey&   attr_key;
144                 char*           attr_value;
145 
146         };  // end class ManetGraphMLParser::Attribute
147 
148         ManetGraphMLParser();
149 
150         // Get existing or create new attribute key
151         AttributeKey* GetAttributeKey(const char* name, AttributeType type, AttributeDomain domain);
152 
153         class GenericAttributeList : public ProtoTreeTemplate<GenericAttribute) {};
154 
155         // These custom Attribute subclasses allow us to organize things for rapid access
156         // (The ItemAttribute class here is a base class for the others)
157         class ItemAttributeBase : public GenericAttribute
158         {
159             public:
160                 virtual ~ItemAttributeBase();
161 
162             protected:
163                 ItemAttributeBase(AttributeKey& key);
164 
165                 bool SetItemKey(const char* itemPtr, unsigned int itemPtrLen);
166 
167                 const char* GetKey() const
168                     {return item_key;}
169                 virtual unsigned int GetKeysize() const = 0;
170 
171             private
172                 char*   item_key;  // concatenation of graph item pointer and attribute id
173         };  // end class ManetGraphMLParser::ItemAttributeBase
174 
175         template <class ITEM_TYPE>
176         class ItemAttribute : public ItemAttributeBase
177         {
178             public:
179                 virtual ~ItemAttribute();
180                 bool SetItem(const ITEM_TYPE& item)
181                 {
182                     const ITEM_PTR* itemPtr = &item;
183                     return SetItemKey(&itemPtr, sizeof(ITEM_TYPE*));
184                 }
185 
186             protected:
187                 ItemAttribute(AttributeKey& key);
188 
189                 unsigned int GetKeysize() const
190                     {return ((sizeof(ITEM_TYPE*) + strlen(attr_key.GetId())) << 3);}
191 
192         };  // end class ManetGraphMLParser::ItemAttribute
193 
194 
195         // Helper method to find graph item attributes from a given attribute list (ProtoTree)
196         Attribute* FindItemAttribute(ProtoTree& attrList, const char* itemPtr, unsigned int itemPtrLen, AttributeKey& attrKey);
197 
198         class NodeAttribute : public ItemAttribute<NetGraph::Node>
199             {public: NodeAttribute(AttributeKey& key) : ItemAttribute(key) {}};
200         class InterfaceAttribute : public ItemAttribute<NetGraph::Interface>
201             {public: InterfaceAttribute(AttributeKey& key) : ItemAttribute(key) {}};
202         class LinkAttribute : public ItemAttribute<NetGraph::Link>
203             {public: LinkAttribute(AttributeKey& key) : ItemAttribute(key) {}};
204         class NodeAttributeList : public ProtoTreeTemplate<NodeAttribute> {};
205         class InterfaceAttributeList : public ProtoTreeTemplate<InterfaceAttribute> {};
206         class LinkAttributeList : public ProtoTreeTemplate<LinkAttribute> {};
207 
208 
209         /////// OLD STUFF ////
210         bool SetGraphID(const char* name);
211 
212         ManetGraphMLParser();
213 
214     private:
215         // Attribute management members
216         AttributeNameList        attr_name_list;
217         AttributeIdList         attr_id_list;
218         AttributeList           graph_attr_list;
219         NodeAttributeList       node_attr_list;
220         InterfaceAttributeList  iface_attr_list;
221         LinkAttributeList       link_attr_list;
222 
223         char *XMLName;
224 
225         const char* FindAttributeIndex(const char* theName);
226         AttributeKey* FindAttributeKey(const char* theName);
227 
228 
229 //        virtual bool WriteKeys(xmlTextWriter* writerPtr, NetGraph& graph) = 0;
230         virtual bool UpdateKeys(NetGraph& graph) = 0; //this will replace the above as all keys will be stored locally
231         bool WriteLocalKeys(xmlTextWriter* writerPtr);
232 
233         virtual NetGraph::Node* CreateNode() = 0;
234 //        virtual bool WriteNodeAttributes(xmlTextWriter* writerPtr,NetGraph::Node& theNode) = 0;
235         virtual bool UpdateNodeAttributes(NetGraph::Node& theNode) = 0; //this will replace the above so keys will be stored locally
236         bool WriteLocalNodeAttributes(xmlTextWriter* writerPtr,NetGraph::Node& theNode);
237 
238         virtual NetGraph::Interface* CreateInterface(NetGraph::Node& node) = 0;
239         virtual NetGraph::Interface* CreateInterface(NetGraph::Node& node,ProtoAddress& addr) = 0;
240         virtual bool InsertInterface(NetGraph::Interface& theIface) = 0;
241         virtual bool AddInterfaceToNode(NetGraph::Node& theNode,NetGraph::Interface& theIface,bool makeDefault = false) = 0;
242         virtual bool AddInterfaceToGraph(NetGraph& theGraph,NetGraph::Interface& theIface) = 0;
243         //virtual bool InsertInterface(NetGraph::Interface& theIface) = 0;
244   //      virtual bool WriteInterfaceAttributes(xmlTextWriter* writerPtr,NetGraph::Interface& theInterface) = 0;
245         virtual bool UpdateInterfaceAttributes(NetGraph::Interface& theInterface) = 0; //this will replace the above so keys will be stored locally
246         bool WriteLocalInterfaceAttributes(xmlTextWriter* writerPtr,NetGraph::Interface& theInterface);
247 
248         virtual NetGraph::Cost* CreateCost(double value) = 0;
249 
250         virtual bool Connect(NetGraph::Interface& iface1, NetGraph::Interface& iface2, NetGraph::Cost& cost, bool isDuplex) = 0;
251 //        virtual bool WriteLinkAttributes(xmlTextWriter* writerPtr,NetGraph::Link& theLink) = 0;
252         virtual bool UpdateLinkAttributes(NetGraph::Link& theLink) = 0; //this will replace the above so keys will be stored locally
253         bool WriteLocalLinkAttributes(xmlTextWriter* writerPtr,NetGraph::Link& theLInk);
254 
255         bool ReadXMLNode(xmlTextReader*   readerPtr,
256                          NetGraph&        graph,
257                          char*            parentXMLNodeID,
258                          bool&            isDuplex);
259 };  // end class ManetGraphMLParser
260 
261 template <class COST_TYPE = ManetGraph::Cost, class IFACE_TYPE = ManetGraph::Interface, class LINK_TYPE = ManetGraph::Link,class NODE_TYPE = ManetGraph::Node>
262 class ManetGraphMLTemplate : public ManetGraphMLParser, public NetGraphTemplate<COST_TYPE, IFACE_TYPE, LINK_TYPE, NODE_TYPE>
263 {
264     public:
265         ManetGraphMLTemplate() {}
266         virtual ~ManetGraphMLTemplate() {}
267 
268         bool Read(const char* path)   // load graph from GraphML file
269             {return ManetGraphMLParser::Read(path, *this);}
270 
271         bool Write(const char* path)  // make GraphML file from graph
272             {return ManetGraphMLParser::Write(*this, path);}
273         bool Connect(NetGraph::Interface& iface1,NetGraph::Interface& iface2,NetGraph::Cost& theCost,bool isDuplex)
274             {return NetGraph::Connect(iface1,iface2,theCost,isDuplex);}
275         virtual bool InsertInterface(NetGraph::Interface& theIface)
276             {return NetGraph::InsertInterface(theIface);}
277     protected:
278   //      virtual bool WriteKeys(xmlTextWriter* writerPtr, NetGraph& theGraph)
279   //          {return true;}
280         virtual bool UpdateKeys(NetGraph& theGraph)
281             {return true;}
282   /*      virtual bool WriteNodeAttributes(xmlTextWriter* writerPtr, NetGraph::Node& theNode)
283             {return true;}
284         virtual bool WriteInterfaceAttributes(xmlTextWriter* writerPtr, NetGraph::Interface& theInterface)
285             {return true;}
286         virtual bool WriteLinkAttributes(xmlTextWriter* writerPtr, NetGraph::Link& theLInk)
287             {return true;}*/
288         virtual bool UpdateNodeAttributes(NetGraph::Node& theNode)
289             {return true;}
290         virtual bool UpdateInterfaceAttributes(NetGraph::Interface& theInterface)
291             {return true;}
292         virtual bool UpdateLinkAttributes(NetGraph::Link& theLInk)
293             {return true;}
294     private:
295         class NetGraph::Node* CreateNode()
296             {return static_cast<NetGraph::Node*>(new NODE_TYPE());}
297         class NetGraph::Interface* CreateInterface(NetGraph::Node& node)
298             {return static_cast<NetGraph::Interface*>(new IFACE_TYPE(static_cast<NODE_TYPE&>(node)));}
299         class NetGraph::Interface* CreateInterface(NetGraph::Node& node,ProtoAddress& addr)
300             {return static_cast<NetGraph::Interface*>(new IFACE_TYPE(static_cast<NODE_TYPE&>(node),addr));}
301         class NetGraph::Cost* CreateCost(double value)
302             {return static_cast<NetGraph::Cost*>(new COST_TYPE(value));}
303         class NetGraph::Cost* CreateCost()
304             {return static_cast<NetGraph::Cost*>(new COST_TYPE());}
305         virtual bool AddInterfaceToNode(NetGraph::Node& theNode,NetGraph::Interface& theIface,bool makeDefault)
306             {return (static_cast<NODE_TYPE&>(theNode)).AddInterface(theIface,makeDefault);}
307         virtual bool AddInterfaceToGraph(NetGraph& theGraph,NetGraph::Interface& theIface)
308             {return (static_cast<ManetGraphMLTemplate&>(theGraph)).InsertInterface(theIface);}
309 };  // end class ManetGraphMLParser
310 
311 
312 //class ManetGraphML : public ManetGraphMLTemplate<> {};
313 
314 #endif // _MANET_GRAPHML
315