[gxml] GomHashMap: New collection using a string key



commit 631d9d36fb09e4871528aa559fc1f844411f4e24
Author: Daniel Espinosa <esodan gmail com>
Date:   Sun Nov 6 13:27:19 2016 -0600

    GomHashMap: New collection using a string key
    
    GomHasMap is a new class collection using an attribute
    string as key. Key attribute should be defined in DomElement
    in order to set() to collection and be used in get().

 gxml/GomCollections.vala       |   77 ++++++++++++++++++++++++++++++++++++++++
 test/GomSerializationTest.vala |   61 +++++++++++++++++++++++++++++++-
 2 files changed, 137 insertions(+), 1 deletions(-)
---
diff --git a/gxml/GomCollections.vala b/gxml/GomCollections.vala
index 256e927..e43c77c 100644
--- a/gxml/GomCollections.vala
+++ b/gxml/GomCollections.vala
@@ -119,3 +119,80 @@ public class GXml.GomArrayList : Object, GomCollection {
     }
   }
 }
+
+
+public class GXml.GomHashMap : Object, GomCollection {
+  protected List<int> _nodes_index = new List<int> ();
+  protected HashTable<string,int> _hashtable = new HashTable<string,int> (str_hash,str_equal);
+  protected GomElement _element;
+  protected string _items_name;
+  protected string _attribute_key;
+  public List<int> nodes_index { get { return _nodes_index; } }
+  public DomElement element {
+    get { return _element; }
+    construct set {
+      if (value != null) {
+        if (value is GomElement)
+          _element = value as GomElement;
+        else
+          GLib.warning (_("Invalid element type only GXmlGomElement is supported"));
+      }
+    }
+  }
+  public string items_name {
+    get { return _items_name; } construct set { _items_name = value; }
+  }
+  public string attribute_key {
+    get { return _attribute_key; } construct set { _attribute_key = value; }
+  }
+
+  public GomHashMap.initialize (GomElement element,
+                                  string items_name,
+                                  string attribute_key) {
+    _element = element;
+    _items_name = items_name;
+    _attribute_key = attribute_key;
+  }
+  /**
+   * Adds an {@link DomElement} of type {@link GomObject} as a child of
+   * {@link element}
+   */
+  public new void set (DomElement node) throws GLib.Error {
+    if (!(node is GomElement))
+      throw new DomError.INVALID_NODE_TYPE_ERROR
+                (_("Invalid atempt to set unsupported type. Only GXmlGomElement is supported"));
+    if (node.owner_document != _element.owner_document)
+      throw new DomError.HIERARCHY_REQUEST_ERROR
+                (_("Invalid atempt to set a node with a different parent document"));
+    var key = node.get_attribute (attribute_key);
+    if (key == null)
+      throw new DomError.HIERARCHY_REQUEST_ERROR
+                (_("Invalid atempt to set a node without key attribute"));
+    _element.append_child (node);
+    if (_element.child_nodes.size == 0)
+      throw new DomError.QUOTA_EXCEEDED_ERROR
+                (_("Invalid atempt to add a node with a different parent document"));
+    var index = _element.child_nodes.size - 1;
+    _nodes_index.append (index);
+    GLib.message ("Key:"+key+" Index: "+index.to_string ());
+    _hashtable.insert (key, index);
+  }
+  public new DomElement? get (string key) {
+    if (!_hashtable.contains (key)) return null;
+    var i = _hashtable.get (key);
+    GLib.message ("Key:"+key+" item:"+i.to_string ());
+    return _element.child_nodes.get (i) as DomElement;
+  }
+  public void search () throws GLib.Error {
+    for (int i = 0; i < _element.child_nodes.size; i++) {
+      var n = _element.child_nodes.get (i);
+      if (n is GomObject) {
+        if ((n as DomElement).local_name.down () == items_name.down ()) {
+          if ((n as DomElement).get_attribute (attribute_key) != null) {
+            this.set (n as DomElement);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/test/GomSerializationTest.vala b/test/GomSerializationTest.vala
index 94892ae..085fb44 100644
--- a/test/GomSerializationTest.vala
+++ b/test/GomSerializationTest.vala
@@ -95,6 +95,16 @@ class GomSerializationTest : GXmlTest  {
       return parser.write_string ();
     }
   }
+  public class BookStore : GomElement {
+    public GomHashMap books { get; set; }
+    construct {
+      _local_name = "BookStore";
+    }
+    public string to_string () {
+      var parser = new XParser (this);
+      return parser.write_string ();
+    }
+  }
   public static void add_tests () {
     Test.add_func ("/gxml/gom-serialization/write/properties", () => {
       var b = new Book ();
@@ -159,7 +169,10 @@ class GomSerializationTest : GXmlTest  {
       assert (s != null);
       GLib.message ("DOC:"+s);
       assert ("<BookStand Classification=\"Science\"/>" in s);
-      try { bs.registers.add (br); } catch {}
+      try {
+        bs.registers.add (br);
+        assert_not_reached ();
+      } catch {}
       br = new BookRegister.document (bs.owner_document);
       br.year = 2016;
       bs.registers.add (br);
@@ -182,6 +195,52 @@ class GomSerializationTest : GXmlTest  {
       assert ((bs.registers.get_item (1) as BookRegister).year == 2010);
       assert ((bs.registers.get_item (2) as BookRegister).year == 2000);
     });
+    Test.add_func ("/gxml/gom-serialization/write/property-hashmap", () => {
+      var bs = new BookStore ();
+      string s = bs.to_string ();
+      assert (s != null);
+      GLib.message ("DOC:"+s);
+      assert ("<BookStore/>" in s);
+      assert (bs.books == null);
+      var b = new Book ();
+      bs.books = new GomHashMap.initialize (bs,b.local_name,"name");
+      s = bs.to_string ();
+      assert (s != null);
+      GLib.message ("DOC:"+s);
+      assert ("<BookStore/>" in s);
+      try {
+        bs.books.set (b);
+        assert_not_reached ();
+      } catch {}
+      b = new Book.document (bs.owner_document);
+      try {
+        bs.books.set (b);
+        assert_not_reached ();
+      } catch {}
+      b.name = "Title1";
+      bs.books.set (b);
+      s = bs.to_string ();
+      assert (s != null);
+      GLib.message ("DOC:"+s);
+      assert ("<BookStore><Book Name=\"Title1\"/></BookStore>" in s);
+      var b2 = new Book.document (bs.owner_document);
+      b2.name = "Title2";
+      bs.books.set (b2);
+      bs.append_child (bs.owner_document.create_element ("Test"));
+      var b3 = new Book.document (bs.owner_document);
+      b3.name = "Title3";
+      bs.books.set (b3);
+      s = bs.to_string ();
+      assert (s != null);
+      GLib.message ("DOC:"+s);
+      assert ("<BookStore><Book Name=\"Title1\"/><Book Name=\"Title2\"/><Test/><Book 
Name=\"Title3\"/></BookStore>" in s);
+      assert (bs.books.get("Title1") != null);
+      assert (bs.books.get("Title2") != null);
+      assert (bs.books.get("Title3") != null);
+      assert ((bs.books.get("Title1") as Book).name == "Title1");
+      assert ((bs.books.get("Title2") as Book).name == "Title2");
+      assert ((bs.books.get("Title3") as Book).name == "Title3");
+    });
     Test.add_func ("/gxml/gom-serialization/read/properties", () => {
       var b = new Book ();
       var parser = new XParser (b);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]