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