[gxml] Added GomHashPairedMap a two key collection map
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] Added GomHashPairedMap a two key collection map
- Date: Tue, 21 Feb 2017 18:34:16 +0000 (UTC)
commit b9a2b61feec126248a4a4102d90b237cfbedfa80
Author: Daniel Espinosa <esodan gmail com>
Date: Tue Feb 21 11:00:16 2017 -0600
Added GomHashPairedMap a two key collection map
gxml/GomCollections.vala | 208 +++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 205 insertions(+), 3 deletions(-)
---
diff --git a/gxml/GomCollections.vala b/gxml/GomCollections.vala
index 5c213a5..899af4d 100644
--- a/gxml/GomCollections.vala
+++ b/gxml/GomCollections.vala
@@ -334,13 +334,14 @@ public class GXml.GomHashMap : GXml.BaseCollection, GXml.GomCollection {
*/
protected HashTable<string,int> _hashtable = new HashTable<string,int> (str_hash,str_equal);
/**
- * Element used to refer of containier element. You should define it at construction time
+ * Element's attribute name used to refer of container's element.
+ * You should define it at construction time
* our set it as a construction property.
*/
protected string _attribute_key;
/**
- * An attribute's name in items to be added and used to retrieve a key to be
- * used in collection.
+ * An attribute's name in items to be added and used to retrieve elements
+ * as key.
*/
public string attribute_key {
get { return _attribute_key; } construct set { _attribute_key = value; }
@@ -402,6 +403,9 @@ public class GXml.GomHashMap : GXml.BaseCollection, GXml.GomCollection {
* Attribute should be a valid {@link DomElement} attribute or
* a {@link GomObject} property identified using a nick with a '::' prefix.
*
+ * If there are more elements with same key, they are keep as child nodes
+ * but the one in collection will be the last one to be found.
+ *
* Return: false if element should not be added to collection.
*/
public override bool validate_append (int index, DomElement element) throws GLib.Error {
@@ -430,3 +434,201 @@ public class GXml.GomHashMap : GXml.BaseCollection, GXml.GomCollection {
return true;
}
}
+
+
+/**
+ * Inteface to be implemented by {@link GomElement} derived classes
+ * in order to provide a string to be used in {@link GomHasMap} as key.
+ *
+ * If {@link GomHashMap} has set its {@link GomHashMap.attribute_key}
+ * its value has precedence over this method.
+ */
+public interface GXml.MappeableElementPairKey : Object, DomElement {
+ public abstract string get_map_primary_key ();
+ public abstract string get_map_secondary_key ();
+}
+
+/**
+ * A class impementing {@link GomCollection} to store references to
+ * child {@link DomElement} of {@link element}, using two attributes in
+ * items as primary and secondary keys or {@link MappeableElementPairKey.map_primary_key}
+ * and {@link MappeableElementPairKey.map_secondary_key} methods if
+ * {@link MappeableElementPairKey} is implemented
+ * by items to be added. If one or both keys are not defined in node,
+ * it is not added; but keeps it as a child node of actual
+ * {@link GomCollection.element}.
+ *
+ * If {@link GomElement} to be added is of type {@link GomCollection.items_type}
+ * and implements {@link MappeableElementPairKey}, you should set
+ * {@link GomHashMap.attribute_primary_key} and {@link GomHashMap.attribute_secondary_key}
+ * to null in order to use returned value of {@link MappeableElementPairKey.map_primary_key}
+ * and {@link MappeableElementPairKey.map_secondary_key}
+ * as keys.
+ *
+ * {{{
+ * public class YourObject : GomElement {
+ * [Description (nick="::Name")]
+ * public string name { get; set; }
+ * public string code { get; set; }
+ * }
+ * public class YourList : GomHashPairedMap {
+ * construct {
+ * try { initialize_with_key (typeof (YourObject),"Name"); }
+ * catch (GLib.Error e) {
+ * warning ("Initialization error for collection type: %s : %s"
+ * .printf (get_type ().name(), e.message));
+ * }
+ * }
+ * }
+ * }}}
+ */
+public class GXml.GomHashPairedMap : GXml.BaseCollection, GXml.GomCollection {
+ /**
+ * A hashtable with all keys as string to node's index refered. Don't modify it manually.
+ */
+ protected HashTable<string,HashTable<string,int>> _hashtable = new HashTable<string,HashTable<string,int>>
(str_hash,str_equal);
+ /**
+ * Element's attribute name used to refer of container's element as primery key.
+ * You should define it at construction time
+ * our set it as a construction property.
+ */
+ protected string _attribute_primary_key;
+ /**
+ * Element's attribute name used to refer of container's element as secondary key.
+ * You should define it at construction time
+ * our set it as a construction property.
+ */
+ protected string _attribute_secondary_key;
+ /**
+ * An attribute's name in items to be added and used to retrieve elements
+ * as primary key.
+ */
+ public string attribute_primary_key {
+ get { return _attribute_primary_key; } construct set { _attribute_primary_key = value; }
+ }
+ /**
+ * An attribute's name in items to be added and used to retrieve elements
+ * as secondary key.
+ */
+ public string attribute_secondary_key {
+ get { return _attribute_secondary_key; } construct set { _attribute_secondary_key = value; }
+ }
+ /**
+ * Convenient function to initialize a {@link GomHashMap} collection, using
+ * given element, items' type and name.
+ */
+ public void initialize_element_with_keys (GomElement element,
+ GLib.Type items_type,
+ string attribute_primary_key,
+ string attribute_secondary_key) throws GLib.Error
+ {
+ initialize (items_type);
+ initialize_element (element);
+ _attribute_primary_key = attribute_primary_key;
+ _attribute_secondary_key = attribute_secondary_key;
+ search ();
+ }
+
+ /**
+ * Convenient function to initialize a {@link GomHashMap} collection, using
+ * given element, items' type and name.
+ *
+ * Using this method at construction time of derived classes.
+ */
+ public void initialize_with_keys (GLib.Type items_type,
+ string attribute_primary_key,
+ string attribute_secondary_key) throws GLib.Error
+ {
+ initialize (items_type);
+ _attribute_primary_key = attribute_primary_key;
+ _attribute_secondary_key = attribute_secondary_key;
+ }
+ /**
+ * Returns an {@link DomElement} in the collection using given string keys.
+ */
+ public new DomElement? get (string primary_key, string secondary_key) {
+ if (!_hashtable.contains (primary_key)) return null;
+ var ht = _hashtable.get (primary_key);
+ if (ht == null) return null;
+ if (!ht.contains (secondary_key)) return null;
+ var i = ht.get (secondary_key);
+ return _element.child_nodes.get (i) as DomElement;
+ }
+ /**
+ * Returns true if @key is used in collection as primery key.
+ */
+ public bool has_primary_key (string key) {
+ if (_hashtable.contains (key)) return true;
+ return false;
+ }
+ /**
+ * Returns true if @key is used in collection as secondary key
+ * with @pkey as primary.
+ */
+ public bool has_secondary_key (string pkey, string key) {
+ if (!(_hashtable.contains (pkey))) return false;
+ var ht = _hashtable.get (pkey);
+ if (ht == null) return false;
+ if (ht.contains (key)) return true;
+ return false;
+ }
+ /**
+ * Returns list of primary keys used in collection.
+ */
+ public GLib.List<string> get_primary_keys () {
+ return _hashtable.get_keys ();
+ }
+ /**
+ * Returns list of secondary keys used in collection with @pkey as primary key.
+ */
+ public GLib.List<string> get_secondary_keys (string pkey) {
+ var l = new GLib.List<string> ();
+ if (!_hashtable.contains (pkey)) return l;
+ var ht = _hashtable.get (pkey);
+ if (ht == null) return l;
+ return ht.get_keys ();
+ }
+ /**
+ * Validates if given element has a {@link GomHashMap.attribute_primary_key}
+ * and {@link GomHashMap.attribute_secondary_key} set,
+ * if so adds a new keys pointing to given index and returns true.
+ *
+ * Attribute should be a valid {@link DomElement} attribute or
+ * a {@link GomObject} property identified using a nick with a '::' prefix.
+ *
+ * If there are more elements with same keys, they are keep as child nodes
+ * but the one in collection will be the last one to be found.
+ *
+ * Return: false if element should not be added to collection.
+ */
+ public override bool validate_append (int index, DomElement element) throws GLib.Error {
+ if (!(element is GomElement)) return false;
+#if DEBUG
+ message ("Validating HashMap Element..."
+ +(element as GomElement).write_string ()
+ +" Attrs:"+(element as GomElement).attributes.length.to_string());
+#endif
+ string pkey = null;
+ string skey = null;
+ if (attribute_primary_key != null && attribute_secondary_key != null) {
+ pkey = (element as DomElement).get_attribute (attribute_primary_key);
+ skey = (element as DomElement).get_attribute (attribute_secondary_key);
+ if (pkey == null || skey == null) {
+ pkey = (element as DomElement).get_attribute (attribute_primary_key.down ());
+ skey = (element as DomElement).get_attribute (attribute_secondary_key.down ());
+ }
+ } else {
+ if (items_type.is_a (typeof(MappeableElementPairKey))) {
+ if (!(element is MappeableElementPairKey)) return false;
+ pkey = ((MappeableElementPairKey) element).get_map_primary_key ();
+ skey = ((MappeableElementPairKey) element).get_map_secondary_key ();
+ }
+ }
+ if (pkey == null || skey == null) return false;
+ var ht = _hashtable.get (pkey);
+ if (ht == null) ht = new HashTable<string,int> (str_hash, str_equal);
+ ht.insert (skey, index);
+ if (!_hashtable.contains (pkey)) _hashtable.insert (pkey, ht);
+ return true;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]