[gxml/serialization] Added new Serializable.transform_(to/from)_string



commit aad75ccf0f0b43533ea71da2ec496741c1cd9c43
Author: Daniel Espinosa <esodan gmail com>
Date:   Mon Oct 28 19:04:25 2013 -0600

    Added new Serializable.transform_(to/from)_string
    
    * Implemented on SerializableJson/ObjectModel returning false
      and as virtual to allow overriding

 gxml/Serializable.vala            |   95 ++++++++++++++++++++++++++++++-------
 gxml/SerializableJson.vala        |   16 ++++++-
 gxml/SerializableObjectModel.vala |   72 +++++++++++++++++-----------
 3 files changed, 136 insertions(+), 47 deletions(-)
---
diff --git a/gxml/Serializable.vala b/gxml/Serializable.vala
index 3196087..4961cc0 100644
--- a/gxml/Serializable.vala
+++ b/gxml/Serializable.vala
@@ -77,7 +77,7 @@ namespace GXml {
                 *
                 * By default is set to object's type's name lowercase.
                 *
-                * This property must be ignored on serialisation.
+                * This property is ignored on serialisation.
                 */
                public abstract string serializable_node_name { get; protected set; }
 
@@ -85,6 +85,8 @@ namespace GXml {
                /**
                 * Store all properties to be ignored on serialization.
                 *
+                * This property is ignored on serialisation.
+                *
                 * Implementors: By default { link list_serializable_properties} initialize
                 * this property to store all public properties, except this one.
                 */
@@ -93,14 +95,14 @@ namespace GXml {
                 * On deserialization stores any { link Node} not used on this
                 * object, but exists in current XML file.
                 *
-                * This property must be ignored on serialisation.
+                * This property is ignored on serialisation.
                 */
                public abstract HashTable<string,GXml.Node>    unknown_serializable_property { get; protected 
set; }
 
                /**
-                * Used by to add content in an { link GXml.Element}.
+                * Used to add content in an { link GXml.Element}.
                 *
-                * This property must be ignored on serialisation.
+                * This property is ignored on serialisation.
                 */
                public abstract string?  serialized_xml_node_value { get; protected set; default = null; }
 
@@ -208,7 +210,8 @@ namespace GXml {
                 * @prop a { link GLib.ParamSpec} describing attribute to deserialize
                 */
                public signal void deserialize_unknown_property_type (Node node, ParamSpec prop);
-               /*
+
+               /**
                 * Handles finding the { link GLib.ParamSpec} for a given property.
                 *
                 * @param property_name the name of a property to obtain a { link GLib.ParamSpec} for
@@ -238,6 +241,10 @@ namespace GXml {
                 */
                public abstract GLib.ParamSpec? find_property_spec (string property_name);
 
+               /**
+                * Default implementation for find_property_spec ().
+                *
+                */
                public virtual GLib.ParamSpec? default_find_property_spec (string property_name) {
                        init_properties ();
                        var props = list_serializable_properties ();
@@ -259,6 +266,10 @@ namespace GXml {
                 */
                public abstract void init_properties ();
 
+               /**
+                * Default implementation for init_properties ().
+                *
+                */
                public virtual void default_init_properties ()
                {
                        if (ignored_serializable_properties == null) {
@@ -279,7 +290,7 @@ namespace GXml {
                        }
                }
 
-               /*
+               /**
                 * List the known properties for an object's class
                 *
                 * @return an array of { link GLib.ParamSpec} of
@@ -308,7 +319,10 @@ namespace GXml {
                 * ones for each call.
                 */
                public abstract GLib.ParamSpec[] list_serializable_properties ();
-
+               /**
+                * Default implementation for list_serializable_properties ().
+                *
+                */
                public virtual GLib.ParamSpec[] default_list_serializable_properties ()
                {
                        init_properties ();
@@ -324,7 +338,7 @@ namespace GXml {
                        return properties;
                }
 
-               /*
+               /**
                 * Get a string version of the specified property
                 *
                 * @param spec The property we're retrieving as a string
@@ -348,13 +362,16 @@ namespace GXml {
                 * `spec` is usually obtained from list_properties or find_property.
                 */
                public abstract void get_property_value (GLib.ParamSpec spec, ref Value val);
-
+               /**
+                * Default implementation for get_property_value ().
+                *
+                */
                public virtual void default_get_property_value (GLib.ParamSpec spec, ref Value val) 
                {
                        if (!ignored_serializable_properties.contains (spec.name))
                                ((GLib.Object)this).get_property (spec.name, ref val);
                }
-               /*
+               /**
                 * Set a property's value.
                 *
                 * @param spec Specifies the property whose value will be set
@@ -377,17 +394,37 @@ namespace GXml {
                 * by the other { link GXml.Serializable} functions.
                 */
                public abstract void set_property_value (GLib.ParamSpec spec, GLib.Value val);
-
+               /**
+                * Default implementation for set_property_value ().
+                *
+                */
                public virtual void default_set_property_value (GLib.ParamSpec spec, GLib.Value val)
                {
                        if (!ignored_serializable_properties.contains (spec.name)) {
                                ((GLib.Object)this).set_property (spec.name, val);
                        }
                }
-                               /* TODO:
-                * - can't seem to pass delegates on struct methods to another function :(
-                * - no easy string_to_gvalue method in GValue :(
+
+               /**
+                * Method to provide custome transformations from strings to
+                * a { link GLib.Value}. Could be used on { link serialize} or simple 
+                * transformations from string.
+                *
+                * Some specialized classes, like derived from { link Serializable} class
+                * implementator, can provide custome transformations.
+                *
+                * Returns: { link true} if transformation was handled, { link false} otherwise.
+                *
+                * Implementors:
+                * To be overrided by derived classes of implementators to provide custome
+                * transformations. Declare it as virtual if you want derived classes of 
+                * implementators to provide custome transformations.
+                * Call this method before use standard Serializable or implementator ones.
+                *
+                * @node a { link GXml.Node} to get attribute from
+                * @prop a { link GLib.ParamSpec} describing attribute to deserialize
                 */
+               public abstract bool transform_from_string (string str, ref GLib.Value dest);
 
                /**
                 * Transforms a string into another type hosted by { link GLib.Value}.
@@ -401,10 +438,6 @@ namespace GXml {
                 * @param dest the #GValue out parameter that will contain the parsed value from the string
                 * @return `true` if parsing succeeded, otherwise `false`
                 */
-               /*
-                * @todo: what do functions written in Vala return in C when
-                * they throw an exception?  NULL/0/FALSE?
-                */
                public static bool string_to_gvalue (string str, ref GLib.Value dest)
                                                     throws SerializableError
                {
@@ -488,6 +521,32 @@ namespace GXml {
                        }
                }
 
+               /**
+                * Method to provide custome transformations from
+                * a { link GLib.Value} to strings. Could be used on { link deserialize} or simple 
+                * transformations to strings.
+                *
+                * Some specialized classes, like derived from { link Serializable} class
+                * implementator, can provide custome transformations.
+                *
+                * Returns: { link true} if transformation was handled, { link false} otherwise.
+                *
+                * Implementors:
+                * To be overrided by derived classes of implementators to provide custome
+                * transformations. Declare it as virtual if you want derived classes of 
+                * implementators to provide custome transformations.
+                * Call this method before use standard Serializable or implementator ones.
+                *
+                * @node a { link GXml.Node} to get attribute from
+                * @prop a { link GLib.ParamSpec} describing attribute to deserialize
+                */
+               public abstract bool transform_to_string (GLib.Value val, ref string str);
+               /**
+                * Transforms a { link GLib.Value} to its string representation.
+                *
+                * By default use GObject standard transformations.
+                *
+                */
                public static string gvalue_to_string (GLib.Value val)
                                                     throws SerializableError
                {
diff --git a/gxml/SerializableJson.vala b/gxml/SerializableJson.vala
index 276bb74..914ac48 100644
--- a/gxml/SerializableJson.vala
+++ b/gxml/SerializableJson.vala
@@ -68,6 +68,15 @@ public class GXml.SerializableJson : GLib.Object, Serializable
                default_set_property_value (spec, val);
        }
 
+       public virtual bool transform_from_string (string str, ref GLib.Value dest)
+       {
+               return false;
+       }
+
+       public virtual bool transform_to_string (GLib.Value val, ref string str)
+       {
+               return false;
+       }
   /**
    * If @node is a Document serialize just add an <Object> element.
    *
@@ -218,7 +227,11 @@ public class GXml.SerializableJson : GLib.Object, Serializable
                                }
                                else {
                                        val = Value (type);
-                                       if (GLib.Value.type_transformable (type, typeof (string))) {
+                                       if (transform_from_string (prop_elem.content, ref val)) {
+                                               this.set_property_value (spec, val);
+                                               return true;
+                                       }
+                                       else if (GLib.Value.type_transformable (type, typeof (string))) {
                                                Serializable.string_to_gvalue (prop_elem.content, ref val);
                                                this.set_property_value (spec, val);
                                                //GLib.message (@"Setting value to property $(spec.name)");
@@ -232,6 +245,7 @@ public class GXml.SerializableJson : GLib.Object, Serializable
 
                                                property_object = Serialization.deserialize_object_from_node 
(prop_elem_child);
                                                val.set_object (property_object);
+                                               return true;
                                        }
                                        else {
                                                deserialize_unknown_property_type (prop_elem, spec);
diff --git a/gxml/SerializableObjectModel.vala b/gxml/SerializableObjectModel.vala
index e1cdb97..f4cb7cf 100644
--- a/gxml/SerializableObjectModel.vala
+++ b/gxml/SerializableObjectModel.vala
@@ -62,6 +62,16 @@ public abstract class GXml.SerializableObjectModel : Object, Serializable
                default_set_property_value (spec, val);
        }
 
+       public virtual bool transform_from_string (string str, ref GLib.Value dest)
+       {
+               return false;
+       }
+
+       public virtual bool transform_to_string (GLib.Value val, ref string str)
+       {
+               return false;
+       }
+
        public Node? serialize (Node node) throws GLib.Error
        {
                Document doc;
@@ -95,33 +105,37 @@ public abstract class GXml.SerializableObjectModel : Object, Serializable
                        var obj = (Serializable) v.get_object ();
                        return obj.serialize (element);
                }
-               Node node = null;
                Value oval = Value (prop.value_type);
                get_property (prop.name, ref oval);
                string val = "";
-               if (Value.type_transformable (prop.value_type, typeof (string)))
-               {
-                       Value rval = Value (typeof (string));
-                       oval.transform (ref rval);
-                       val = rval.dup_string ();
-                       string attr_name;
-                       if (serializable_property_use_nick &&
-                           prop.get_nick () != null &&
-                           prop.get_nick () != "")
-                               attr_name = prop.get_nick ();
-                       else
-                               attr_name = prop.get_name ();
-                       var attr = element.get_attribute_node (attr_name);
-                       if (attr == null) {
-                               //GLib.message (@"New Attr to add... $(attr_name)");
-                               element.set_attribute (attr_name, val);
+               if (!transform_to_string (oval, ref val)) {
+                       if (Value.type_transformable (prop.value_type, typeof (string)))
+                       {
+                               Value rval = Value (typeof (string));
+                               oval.transform (ref rval);
+                               val = rval.dup_string ();
+                       }
+                       else {
+                               Node node = null;
+                               this.serialize_unknown_property (element, prop, out node);
+                               return node;
                        }
-                       else
-                               attr.value = val;
-                       return (Node) attr;
                }
-               this.serialize_unknown_property (element, prop, out node);
-               return node;
+               string attr_name;
+               if (serializable_property_use_nick &&
+                   prop.get_nick () != null &&
+                   prop.get_nick () != "")
+                       attr_name = prop.get_nick ();
+               else
+                       attr_name = prop.get_name ();
+               var attr = element.get_attribute_node (attr_name);
+               if (attr == null) {
+                       //GLib.message (@"New Attr to add... $(attr_name)");
+                       element.set_attribute (attr_name, val);
+               }
+               else
+                       attr.value = val;
+               return (Node) attr;
        }
        
        public virtual Node? deserialize (Node node)
@@ -196,12 +210,14 @@ public abstract class GXml.SerializableObjectModel : Object, Serializable
                        }
                        if (property_node is GXml.Attr)
                        {
-                               Value ptmp = Value (typeof (string));
-                               ptmp.set_string (property_node.node_value);
-                               if (Value.type_transformable (typeof (string), prop.value_type))
-                                       ret = ptmp.transform (ref val);
-                               else
-                                       ret = string_to_gvalue (property_node.node_value, ref val);
+                               if (!transform_from_string (property_node.node_value, ref val)) {
+                                       Value ptmp = Value (typeof (string));
+                                       ptmp.set_string (property_node.node_value);
+                                       if (Value.type_transformable (typeof (string), prop.value_type))
+                                               ret = ptmp.transform (ref val);
+                                       else
+                                               ret = string_to_gvalue (property_node.node_value, ref val);
+                               }
                                set_property (prop.name, val);
                                return ret;
                        }


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