[json-glib] serializable: Allow introspecting properties



commit 96b1e6b50f355c04e794ad7366bd33b9c3d1f81b
Author: Emmanuele Bassi <ebassi linux intel com>
Date:   Wed Jun 1 12:35:58 2011 +0100

    serializable: Allow introspecting properties
    
    This allows a Serializable implementation to override the property list,
    and the setter and the getter function.

 json-glib/json-gobject.c      |   43 +++++++++++++++++-----
 json-glib/json-gobject.h      |   22 +++++++++++
 json-glib/json-serializable.c |   81 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 137 insertions(+), 9 deletions(-)
---
diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c
index a653712..fb97bd4 100644
--- a/json-glib/json-gobject.c
+++ b/json-glib/json-gobject.c
@@ -180,7 +180,9 @@ json_gobject_new (GType       gtype,
 {
   JsonSerializableIface *iface = NULL;
   JsonSerializable *serializable = NULL;
+  gboolean find_property;
   gboolean deserialize_property;
+  gboolean set_property;
   GList *members, *members_left, *l;
   guint n_members;
   GObjectClass *klass;
@@ -268,10 +270,16 @@ json_gobject_new (GType       gtype,
     {
       serializable = JSON_SERIALIZABLE (retval);
       iface = JSON_SERIALIZABLE_GET_IFACE (serializable);
+      find_property = (iface->find_property != NULL);
       deserialize_property = (iface->deserialize_property != NULL);
+      set_property = (iface->set_property != NULL);
     }
   else
-    deserialize_property = FALSE;
+    {
+      find_property = FALSE;
+      deserialize_property = FALSE;
+      set_property = FALSE;
+    }
 
   g_object_freeze_notify (retval);
 
@@ -283,8 +291,12 @@ json_gobject_new (GType       gtype,
       GValue value = { 0, };
       gboolean res = FALSE;
 
-      pspec = g_object_class_find_property (klass, member_name);
-      if (!pspec)
+      if (find_property)
+        pspec = json_serializable_find_property (serializable, member_name);
+      else
+        pspec = g_object_class_find_property (klass, member_name);
+
+      if (pspec == NULL)
         continue;
 
       /* we should have dealt with these above */
@@ -314,15 +326,16 @@ json_gobject_new (GType       gtype,
           res = json_deserialize_pspec (&value, pspec, val);
         }
 
-      /* FIXME - we probably want to be able to have a custom
-       * set_property() for Serializable implementations
-       */
       if (res)
         {
           JSON_NOTE (GOBJECT, "Calling set_property('%s', '%s')",
                      pspec->name,
                      g_type_name (G_VALUE_TYPE (&value)));
-          g_object_set_property (retval, pspec->name, &value);
+
+          if (set_property)
+            json_serializable_set_property (serializable, pspec, &value);
+          else
+            g_object_set_property (retval, pspec->name, &value);
         }
       else
 	g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"",
@@ -345,7 +358,9 @@ json_gobject_dump (GObject *gobject)
 {
   JsonSerializableIface *iface = NULL;
   JsonSerializable *serializable = NULL;
+  gboolean list_properties = FALSE;
   gboolean serialize_property = FALSE;
+  gboolean get_property = FALSE;
   JsonObject *object;
   GParamSpec **pspecs;
   guint n_pspecs, i;
@@ -354,12 +369,18 @@ json_gobject_dump (GObject *gobject)
     {
       serializable = JSON_SERIALIZABLE (gobject);
       iface = JSON_SERIALIZABLE_GET_IFACE (gobject);
+      list_properties = (iface->list_properties != NULL);
       serialize_property = (iface->serialize_property != NULL);
+      get_property = (iface->get_property != NULL);
     }
 
   object = json_object_new ();
 
-  pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
+  if (list_properties)
+    pspecs = json_serializable_list_properties (serializable, &n_pspecs);
+  else
+    pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs);
+
   for (i = 0; i < n_pspecs; i++)
     {
       GParamSpec *pspec = pspecs[i];
@@ -371,7 +392,11 @@ json_gobject_dump (GObject *gobject)
         continue;
 
       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
-      g_object_get_property (gobject, pspec->name, &value);
+
+      if (get_property)
+        json_serializable_get_property (serializable, pspec, &value);
+      else
+        g_object_get_property (gobject, pspec->name, &value);
 
       /* if there is a serialization vfunc, then it is completely responsible
        * for serializing the property, possibly by calling the implementation
diff --git a/json-glib/json-gobject.h b/json-glib/json-gobject.h
index 9eb6ac9..6c02ff9 100644
--- a/json-glib/json-gobject.h
+++ b/json-glib/json-gobject.h
@@ -65,6 +65,17 @@ struct _JsonSerializableIface
                                       GValue           *value,
                                       GParamSpec       *pspec,
                                       JsonNode         *property_node);
+
+  GParamSpec * (* find_property)       (JsonSerializable *serializable,
+                                        const char       *name);
+  GParamSpec **(* list_properties)     (JsonSerializable *serializable,
+                                        guint            *n_pspecs);
+  void         (* set_property)        (JsonSerializable *serializable,
+                                        GParamSpec       *pspec,
+                                        const GValue     *value);
+  void         (* get_property)        (JsonSerializable *serializable,
+                                        GParamSpec       *pspec,
+                                        GValue           *value);
 };
 
 GType     json_serializable_get_type (void) G_GNUC_CONST;
@@ -79,6 +90,17 @@ gboolean  json_serializable_deserialize_property         (JsonSerializable *seri
                                                           GParamSpec       *pspec,
                                                           JsonNode         *property_node);
 
+GParamSpec *    json_serializable_find_property         (JsonSerializable *serializable,
+                                                         const char       *name);
+GParamSpec **   json_serializable_list_properties       (JsonSerializable *serializable,
+                                                         guint            *n_pspecs);
+void            json_serializable_set_property          (JsonSerializable *serializable,
+                                                         GParamSpec       *pspec,
+                                                         const GValue     *value);
+void            json_serializable_get_property          (JsonSerializable *serializable,
+                                                         GParamSpec       *pspec,
+                                                         GValue           *value);
+
 JsonNode *json_serializable_default_serialize_property   (JsonSerializable *serializable,
                                                           const gchar      *property_name,
                                                           const GValue     *value,
diff --git a/json-glib/json-serializable.c b/json-glib/json-serializable.c
index c29cf9a..cd8ec1e 100644
--- a/json-glib/json-serializable.c
+++ b/json-glib/json-serializable.c
@@ -126,6 +126,36 @@ json_serializable_real_serialize (JsonSerializable *serializable,
   return json_serialize_pspec (value, pspec);
 }
 
+static GParamSpec *
+json_serializable_real_find_property (JsonSerializable *serializable,
+                                      const char       *name)
+{
+  return g_object_class_find_property (G_OBJECT_GET_CLASS (serializable), name);
+}
+
+static GParamSpec **
+json_serializable_real_list_properties (JsonSerializable *serializable,
+                                        guint            *n_pspecs)
+{
+  return g_object_class_list_properties (G_OBJECT_GET_CLASS (serializable), n_pspecs);
+}
+
+static void
+json_serializable_real_set_property (JsonSerializable *serializable,
+                                     GParamSpec       *pspec,
+                                     const GValue     *value)
+{
+  g_object_set_property (G_OBJECT (serializable), pspec->name, value);
+}
+
+static void
+json_serializable_real_get_property (JsonSerializable *serializable,
+                                     GParamSpec       *pspec,
+                                     GValue           *value)
+{
+  g_object_get_property (G_OBJECT (serializable), pspec->name, value);
+}
+
 /* typedef to satisfy G_DEFINE_INTERFACE's naming */
 typedef JsonSerializableIface   JsonSerializableInterface;
 
@@ -134,6 +164,10 @@ json_serializable_default_init (JsonSerializableInterface *iface)
 {
   iface->serialize_property = json_serializable_real_serialize;
   iface->deserialize_property = json_serializable_real_deserialize;
+  iface->find_property = json_serializable_real_find_property;
+  iface->list_properties = json_serializable_real_list_properties;
+  iface->set_property = json_serializable_real_set_property;
+  iface->get_property = json_serializable_real_get_property;
 }
 
 G_DEFINE_INTERFACE (JsonSerializable, json_serializable, G_TYPE_OBJECT);
@@ -229,3 +263,50 @@ json_serializable_default_deserialize_property (JsonSerializable *serializable,
                                              value, pspec,
                                              property_node);
 }
+
+GParamSpec *
+json_serializable_find_property (JsonSerializable *serializable,
+                                 const char       *name)
+{
+  g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  return JSON_SERIALIZABLE_GET_IFACE (serializable)->find_property (serializable, name);
+}
+
+GParamSpec **
+json_serializable_list_properties (JsonSerializable *serializable,
+                                   guint            *n_pspecs)
+{
+  g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL);
+
+  return JSON_SERIALIZABLE_GET_IFACE (serializable)->list_properties (serializable, n_pspecs);
+}
+
+void
+json_serializable_set_property (JsonSerializable *serializable,
+                                GParamSpec       *pspec,
+                                const GValue     *value)
+{
+  g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (value != NULL);
+
+  JSON_SERIALIZABLE_GET_IFACE (serializable)->set_property (serializable,
+                                                            pspec,
+                                                            value);
+}
+
+void
+json_serializable_get_property (JsonSerializable *serializable,
+                                GParamSpec       *pspec,
+                                GValue           *value)
+{
+  g_return_if_fail (JSON_IS_SERIALIZABLE (serializable));
+  g_return_if_fail (G_IS_PARAM_SPEC (pspec));
+  g_return_if_fail (value != NULL);
+
+  JSON_SERIALIZABLE_GET_IFACE (serializable)->get_property (serializable,
+                                                            pspec,
+                                                            value);
+}



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