[gxml] GomCollection: Added generic collection interfaces



commit 2ec65fabcc1bfe2b0a05600ba61fe24d085a7260
Author: Daniel Espinosa <esodan gmail com>
Date:   Wed Feb 7 13:46:55 2018 -0600

    GomCollection: Added generic collection interfaces
    
    New GomList, GomMap, GomPairedMap, GomThreeMap, implemented
    by GomArrayList, GomHashMap, GomHashPairedMap and GomHashThreeMap
    respectively.
    
    GomCollection, no more requires Gee's Traversable, Iterable,
    in order to keep backward compatilibity.

 gxml/GomCollections.vala       |  210 +++++++++++++++++++++++++++++++++++++--
 test/GomSerializationTest.vala |   78 +++++++++++++++
 2 files changed, 277 insertions(+), 11 deletions(-)
---
diff --git a/gxml/GomCollections.vala b/gxml/GomCollections.vala
index 07cf535..43f82a0 100644
--- a/gxml/GomCollections.vala
+++ b/gxml/GomCollections.vala
@@ -25,7 +25,7 @@ using Gee;
  * A DOM4 interface to keep references to {@link DomElement} in a {@link element}
  * child nodes. Only {@link GomObject} are supported.
  */
-public interface GXml.GomCollection : Object, Traversable, Iterable
+public interface GXml.GomCollection : Object
 {
   /**
    * A list of child {@link DomElement} objects of {@link element}
@@ -286,9 +286,15 @@ public abstract class GXml.BaseCollection : Object, Traversable<DomElement>, Ite
       pos = -1;
     }
 
-    public DomElement @get ()
+    public new DomElement @get ()
       requires (pos >= 0 && pos < _collection.length) {
-      return _collection.get_item (pos);
+      DomElement e = null;
+      try {
+        e = _collection.get_item (pos);
+      } catch (GLib.Error e) {
+        warning (_("Error: %s").printf (e.message));
+      }
+      return e;
     }
     public bool has_next () { return (pos + 1 < _collection.length); }
     public bool next () {
@@ -297,10 +303,15 @@ public abstract class GXml.BaseCollection : Object, Traversable<DomElement>, Ite
       return true;
     }
     public void remove () {
-      var n = _collection.get_item (pos);
-      if (n == null) return;
-      n.remove ();
-      _collection.search ();
+      DomElement e = null;
+      try {
+        e = _collection.get_item (pos);
+        if (e == null) return;
+        e.remove ();
+        _collection.search ();
+      } catch (GLib.Error e) {
+        warning (_("Error: %s").printf (e.message));
+      }
     }
 
     public bool @foreach (ForallFunc<DomElement> f) {
@@ -314,6 +325,11 @@ public abstract class GXml.BaseCollection : Object, Traversable<DomElement>, Ite
 }
 
 /**
+ * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GomCollection}
+ */
+public interface GXml.GomList : Object, GomCollection, Traversable<DomElement>, Iterable<DomElement> {}
+
+/**
  * A class impementing {@link GomCollection} to store references to
  * child {@link DomElement} of {@link GomCollection.element}, using an index.
  *
@@ -333,7 +349,7 @@ public abstract class GXml.BaseCollection : Object, Traversable<DomElement>, Ite
  *   }
  * }}}
  */
-public class GXml.GomArrayList : GXml.BaseCollection {
+public class GXml.GomArrayList : GXml.BaseCollection, GomList {
   public override bool validate_append (int index, DomElement element) throws GLib.Error {
 #if DEBUG
     GLib.message ("Adding node:"+element.node_name);
@@ -353,6 +369,31 @@ public interface GXml.MappeableElement : Object, DomElement {
   public abstract string get_map_key ();
 }
 
+
+/**
+ * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GomCollection}
+ */
+public interface GXml.GomMap : Object, GomCollection, Traversable<DomElement>, Iterable<DomElement> {
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as key.
+   */
+  public abstract string attribute_key { get; construct set; }
+  /**
+   * Returns an {@link DomElement} in the collection using a string key.
+   */
+  public abstract DomElement? get (string key);
+  /**
+   * Returns true if @key is used in collection.
+   */
+  public abstract bool has_key (string key);
+  /**
+   * Returns list of keys used in collection.
+   */
+  public abstract Set<string> keys_set { owned get; }
+}
+
+
 /**
  * A class impementing {@link GomCollection} to store references to
  * child {@link DomElement} of {@link GomCollection.element}, using an attribute in
@@ -381,7 +422,7 @@ public interface GXml.MappeableElement : Object, DomElement {
  *   }
  * }}}
  */
-public class GXml.GomHashMap : GXml.BaseCollection {
+public class GXml.GomHashMap : GXml.BaseCollection, GomMap {
   /**
    * A hashtable with all keys as string to node's index refered. Don't modify it manually.
    */
@@ -490,6 +531,13 @@ public class GXml.GomHashMap : GXml.BaseCollection {
   public override void clear () {
     _hashtable = new HashMap<string,int> ();
   }
+  public Gee.Set<string> keys_set {
+    owned get {
+      var l = new HashSet<string> ();
+      foreach (string k in _hashtable.keys) { l.add (k); }
+      return l;
+    }
+  }
 }
 
 
@@ -502,6 +550,44 @@ public interface GXml.MappeableElementPairKey : Object, DomElement {
   public abstract string get_map_secondary_key ();
 }
 
+
+/**
+ * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GomCollection}
+ */
+public interface GXml.GomPairedMap : Object, GomCollection, Traversable<DomElement>, Iterable<DomElement> {
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as primary key.
+   */
+  public abstract string attribute_primary_key { get; construct set; }
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as secondary key.
+   */
+  public abstract string attribute_secondary_key { get; construct set; }
+  /**
+   * Returns list of primary keys used in collection.
+   */
+  public abstract Set<string> primary_keys_set { owned get; }
+  /**
+   * Returns an {@link DomElement} in the collection using given string keys.
+   */
+  public abstract DomElement? get (string primary_key, string secondary_key);
+  /**
+   * Returns true if @key is used in collection as primery key.
+   */
+  public abstract bool has_primary_key (string key);
+  /**
+   * Returns true if @key is used in collection as secondary key
+   * with @pkey as primary.
+   */
+  public abstract bool has_secondary_key (string pkey, string key);
+  /**
+   * Returns list of secondary keys used in collection with @pkey as primary key.
+   */
+  public abstract Set<string> secondary_keys_set (string pkey);
+}
+
 /**
  * A class impementing {@link GomCollection} to store references to
  * child {@link DomElement} of {@link GomCollection.element}, using two attributes in
@@ -538,7 +624,7 @@ public interface GXml.MappeableElementPairKey : Object, DomElement {
  *   }
  * }}}
  */
-public class GXml.GomHashPairedMap : GXml.BaseCollection {
+public class GXml.GomHashPairedMap : GXml.BaseCollection, GomPairedMap {
   /**
    * A hashtable with all keys as string to node's index refered. Don't modify it manually.
    */
@@ -698,6 +784,24 @@ public class GXml.GomHashPairedMap : GXml.BaseCollection {
   public override void clear () {
     _hashtable = new HashMap<string,HashMap<string,int>> ();
   }
+  public Set<string> primary_keys_set {
+    owned get {
+      var l = new HashSet<string> ();
+      foreach (string k in _hashtable.keys) {
+        l.add (k);
+      }
+      return l;
+    }
+  }
+  public Set<string> secondary_keys_set (string pkey) {
+    var l = new HashSet<string> ();
+    var ht = _hashtable.get (pkey);
+    if (ht == null) return l;
+    foreach (string k in ht.keys) {
+      l.add (k);
+    }
+    return l;
+  }
 }
 
 
@@ -723,6 +827,59 @@ public interface GXml.MappeableElementThreeKey : Object, DomElement {
   public abstract string get_map_tkey ();
 }
 
+
+/**
+ * {@link Gee.Iterable} and {@link Gee.Traversable} implementation of {@link GomCollection}
+ */
+public interface GXml.GomThreeMap : Object, GomCollection, Traversable<DomElement>, Iterable<DomElement> {
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as primary key.
+   */
+  public abstract string attribute_primary_key { get; construct set; }
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as secondary key.
+   */
+  public abstract string attribute_secondary_key { get; construct set; }
+  /**
+   * An attribute's name in items to be added and used to retrieve elements
+   * as third key.
+   */
+  public abstract string attribute_third_key { get; construct set; }
+  /**
+   * Returns list of primary keys used in collection.
+   */
+  public abstract Set<string> primary_keys_set { owned get; }
+  /**
+   * Returns an {@link DomElement} in the collection using given string keys.
+   */
+  public abstract DomElement? get (string primary_key, string secondary_key, string third_key);
+  /**
+   * Returns true if @key is used in collection as primery key.
+   */
+  public abstract bool has_primary_key (string key);
+  /**
+   * Returns true if @key is used in collection as secondary key
+   * with @pkey as primary.
+   */
+  public abstract bool has_secondary_key (string pkey, string key);
+  /**
+   * Returns true if @key is used in collection as third key with secondary key
+   * and pkey as primary.
+   */
+  public abstract bool has_third_key (string pkey, string skey, string key);
+  /**
+   * Returns list of secondary keys used in collection with @pkey as primary key.
+   */
+  public abstract Set<string> secondary_keys_set (string pkey);
+  /**
+   * Returns list of third keys used in collection with pkey as primary key
+   * and skey as secondary key.
+   */
+  public abstract Set<string> third_keys_set (string pkey, string skey);
+}
+
 /**
  * A class impementing {@link GomCollection} to store references to
  * child {@link DomElement} of {@link GomCollection.element}, using three attributes in
@@ -764,7 +921,7 @@ public interface GXml.MappeableElementThreeKey : Object, DomElement {
  *   }
  * }}}
  */
-public class GXml.GomHashThreeMap : GXml.BaseCollection {
+public class GXml.GomHashThreeMap : GXml.BaseCollection, GomThreeMap {
   /**
    * A hashtable with all keys as string to node's index refered. Don't modify it manually.
    */
@@ -975,4 +1132,35 @@ public class GXml.GomHashThreeMap : GXml.BaseCollection {
   public override void clear () {
     _hashtable = new HashMap<string,HashMap<string,HashMap<string,int>>> ();
   }
+  public Set<string> primary_keys_set {
+    owned get {
+      var l = new HashSet<string> ();
+      foreach (string k in _hashtable.keys) {
+        l.add (k);
+      }
+      return l;
+    }
+  }
+  public Set<string> secondary_keys_set (string pkey) {
+    var l = new HashSet<string> ();
+    if (!_hashtable.has_key (pkey)) return l;
+    var ht = _hashtable.get (pkey);
+    if (ht == null) return l;
+    foreach (string k in ht.keys) {
+      l.add (k);
+    }
+    return l;
+  }
+  public Set<string> third_keys_set (string pkey, string skey) {
+    var l = new HashSet<string> ();
+    if (!_hashtable.has_key (pkey)) return l;
+    var ht = _hashtable.get (pkey);
+    if (ht == null) return l;
+    var hte = ht.get (skey);
+    if (hte == null) return l;
+    foreach (string k in hte.keys) {
+      l.add (k);
+    }
+    return l;
+  }
 }
diff --git a/test/GomSerializationTest.vala b/test/GomSerializationTest.vala
index 22a9d9b..329fa64 100644
--- a/test/GomSerializationTest.vala
+++ b/test/GomSerializationTest.vala
@@ -1375,6 +1375,84 @@ class GomSerializationTest : GXmlTest  {
         assert ((e as Book).name == "Title %d".printf (n));
         n++;
       }
+      var bst = new BookStand ();
+      bst.set_instance_property ("registers");
+      var r = bst.registers;
+      assert (r.items_type.is_a (typeof (BookRegister)));
+      n = 1;
+      for (int i = 0; i < 10; i++) {
+        var b = r.create_item () as BookRegister;
+        assert (b != null);
+        b.year = 2000 + n;
+        n++;
+        r.append (b);
+      }
+      n = 1;
+      foreach (DomElement e in r) {
+        assert ((e as BookRegister) != null);
+        assert ((e as BookRegister).year == 2000 + n);
+        n++;
+      }
+      bst.set_instance_property ("hashmap-registers");
+      var hr = bst.hashmap_registers;
+      n = 1;
+      for (int i = 0; i < 10; i++) {
+        var b = hr.create_item () as BookRegister;
+        assert (b != null);
+        b.set_instance_property ("book");
+        b.book.name = "book%d".printf (n);
+        b.year = 2000 + n;
+        n++;
+        hr.append (b);
+      }
+      n = 1;
+      foreach (DomElement e in hr) {
+        assert ((e as BookRegister) != null);
+        assert ((e as BookRegister).year == 2000 + n);
+        n++;
+      }
+
+      bst.set_instance_property ("hashpair-registers");
+      var hpr = bst.hashpair_registers;
+      n = 1;
+      for (int i = 0; i < 10; i++) {
+        var b = hpr.create_item () as BookRegister;
+        assert (b != null);
+        b.set_instance_property ("book");
+        b.book.name = "book%d".printf (n);
+        b.year = 2000 + n;
+        n++;
+        hpr.append (b);
+      }
+      n = 1;
+      foreach (DomElement e in hpr) {
+        assert ((e as BookRegister) != null);
+        assert ((e as BookRegister).book.name == "book%d".printf (n));
+        assert ((e as BookRegister).year ==  2000 + n);
+        n++;
+      }
+
+      bst.set_instance_property ("hashthree-registers");
+      var htr = bst.hashthree_registers;
+      n = 1;
+      for (int i = 0; i < 10; i++) {
+        var b = htr.create_item () as BookRegister;
+        assert (b != null);
+        b.set_instance_property ("book");
+        b.book.name = "book%d".printf (n);
+        b.year = 2000 + n;
+        b.cover = "cover%d".printf (n);
+        n++;
+        htr.append (b);
+      }
+      n = 1;
+      foreach (DomElement e in htr) {
+        assert ((e as BookRegister) != null);
+        assert ((e as BookRegister).book.name == "book%d".printf (n));
+        assert ((e as BookRegister).year == 2000 + n);
+        assert ((e as BookRegister).cover == "cover%d".printf (n));
+        n++;
+      }
     } catch (GLib.Error e) {
       GLib.message ("Error: "+e.message);
       assert_not_reached ();


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